Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/Tools/3dsmaxExport/MaxscriptExport/scripts/ogre/lib/OgreBipedLib.ms @ 6

Last change on this file since 6 was 6, checked in by anonymous, 17 years ago

=…

File size: 16.4 KB
Line 
1include "ogre/lib/ogreSkeletonLib_usefulfns.ms"
2
3-----------------------------------------------------------------------------
4-- gets  keyframes from the controllers animation
5-----------------------------------------------------------------------------
6function getTimeList obj firstframe lastframe samplerate IKsamplerate =
7(
8        local list,rotContr,posContr,e  ;
9        list = #(firstframe) ;
10        list2 = #() ; -- this is the list which will be returned.
11       
12        -- Biped Bones and the root: Bip01 for example don't have the same controller
13       
14        -- Root : Bip01
15        if (isPelvis obj) then (
16                -- vertical controller
17                for e in obj.controller.vertical.controller.keys do (
18                        t =e.time ;
19                        if (t>firstFrame and t<=lastFrame) then (
20                                append list t ;
21                                --print t ;     
22                        )
23                )
24                -- horizontal controller
25                for e in obj.controller.horizontal.controller.keys do (
26                        t =e.time ;
27                        if (t>firstFrame and t<=lastFrame) then
28                                append list t ;
29                )
30                -- turn controller
31                for e in obj.controller.turning.controller.keys do (
32                        t =e.time ;
33                        if (t>firstFrame and t<=lastFrame) then
34                                append list t ;
35                )
36                sort list ;
37        )
38        -- Biped Bones
39        else if (isKindOf obj Biped_Object) then (
40               
41                for e in obj.controller.keys do (
42                        t =e.time ;
43                        if (t>firstFrame and t<=lastFrame) then
44                                append list t ;
45                )
46        )
47        -- Standard Bones
48        else
49        (
50                --print obj.name;
51                --print (classof obj.controller) ;
52                if (classof obj.controller == prs) then         -- standard controller
53                (
54                        rotContr = obj.rotation.controller ;
55                        posContr = obj.pos.controller ;
56               
57                        for e in rotContr.keys do
58                        (
59                                t = e.time ;
60                                if (t>firstFrame and t<=lastFrame) then
61                                        append list t ;
62                        )
63                        for e in posContr.keys do
64                        (
65                                t = e.time ;
66                                if (t>firstFrame and t<=lastFrame) then
67                                        append list t ;
68                        )       
69                )
70                else if ((classof obj.controller == IK_ControllerMatrix3Controller) or (classof obj.controller == IKControl)) then              -- IK controller
71                (
72                        local IKSR = IKsamplerate;
73                       
74                        if (IKSR == 0.0) then
75                                IKSR = 1.0;
76                       
77                        i=firstFrame as Float;
78                        while (i<=lastFrame) do
79                        (
80                                append list (i as Float);                       
81                                i = i + IKSR;
82                        )
83                )
84        )
85
86        append list (firstFrame as Float);              -- add a keyframe on the first frame
87        append list (lastFrame as Float);               -- add a keyframe on then last frame
88
89        if (samplerate > 0) then                                -- sample the animation by adding keyframes on regular intervals
90        (
91                i=firstFrame as Float;
92                while (i<=lastFrame) do
93                (
94                        append list (i as Float);                       
95                        i = i + samplerate;
96                )
97        )
98        sort list ;
99       
100        -- if several keyframes have the same value, we keep just one
101        keepLoneValues list list2 ;
102        list2 ;
103)
104
105
106-----------------------------------------------------------------------------
107-- write <track />
108-- Selected keys belongs to [firstframe,lastFrame]
109-- time = (key.time - firstFrame)*length/(lastFrame-firstFrame)
110--   (e.g. first key has time 0.)
111-----------------------------------------------------------------------------
112function writeTrack bone_name boneId firstframe lastframe samplerate IKsamplerate length scale flipYZ outFile=
113(
114        local angle,timef,i,bname,d,mref,mparent ;
115       
116        -- displays information in the maxscript listener
117        if (not g_MAX) then
118                format "retrieving key information for % ...\n" (bone_name) ;
119
120        -- gets bone acording to the parameter boneId
121        bname = bone_name ;
122        replaceSpaces bname ;
123        d = getNodeByName bname ;
124       
125        -- gets keyframe list
126        timelist = getTimeList d firstframe lastframe samplerate IKsamplerate;
127       
128        -- track header
129        format("\t\t\t\t<track bone = \"%\">\n") bname to:outFile ;
130        format("\t\t\t\t\t<keyframes>\n") to:outFile ;
131       
132        -- gets initial transform at frame 0f
133        at time 0f (
134                initTform = d.transform ;
135                if (not isRootUniversal2 d) then (
136                        mparent = d.parent.transform ;
137                        initTform = initTform*inverse(mparent) ;
138                )
139                else if (flipYZ) then (
140                        if (not g_MAX) then
141                                format " - flipping root track..." ;
142                        -- we add the bip Transform
143                        --initTform = initTform * d.controller.rootNode.transform ;
144                        initTform = flipYZTransform initTform ;
145                )
146        )
147               
148        -- for each frame in the list
149        for i in timelist do
150        (
151                -- moves slider time and compute OGRE time
152                at time i (
153                        timef = ((float) (i-firstFrame)*length)/(lastframe - firstframe ) ;
154                       
155                -- First, rotation which depends on initial transformation
156                        Tform = d.transform ;
157                        -- if this is the pelvis
158                        if (isRootUniversal2 d) then (
159                                mparent = matrix3 1 ;
160                                -- if flipYZ == true
161                                if (flipYZ) then
162                                        Tform = flipYZTransform Tform ;
163                        )                       
164                        else
165                                mparent = d.parent.transform ;
166                       
167                        -- computes rotation
168                        mref = initTform*mparent ;     
169                        Tform = Tform*inverse(mref) ;
170                       
171                        -- rotation part is saved.
172                        --rot = Tform.rotation as angleaxis ;
173                        --angle = - degToRad (rot.angle) ; -- don't know why there must be this minus :((((((
174                        rot = toAngleAxis Tform.rotation ;
175                        axis = rot.axis;
176                        angle = - rot.angle;
177                       
178                        -- Then, position which depends on parent                       
179                        Tform=d.transform ;
180                        Tform=Tform*inverse(mparent) ;
181                       
182                        -- if this is the root bone and flipYZ == true
183                        if (isRootUniversal2 d and flipYZ) then (
184                                Tform = flipYZTransform Tform ;
185                        )
186                       
187                        -- substracts position of the initial transform
188                        Tform.pos -= initTform.pos ;
189                        Tform.pos = Tform.pos * scale ;
190                       
191                        pos = Tform.pos ;
192
193                        -- writes them !
194                        if (abs(pos.x)<1e-5) then pos.x = 0 ;
195                        if (abs(pos.y)<1e-5) then pos.y = 0 ;
196                        if (abs(pos.z)<1e-5) then pos.z = 0 ;
197                       
198                        format("\t\t\t\t\t\t<keyframe time=\"%\">\n") timef to: outFile ;
199                        format("\t\t\t\t\t\t\t<translate x=\"%\" y=\"%\" z=\"%\" />\n") pos.x pos.y pos.z to: outFile ;
200                        format("\t\t\t\t\t\t\t<rotate angle=\"%\">\n") angle to:outFile ;
201                        format("\t\t\t\t\t\t\t\t<axis x=\"%\" y=\"%\" z=\"%\" />\n") (axis.x) (axis.y) (axis.z) to:outFile ;
202                        format("\t\t\t\t\t\t\t</rotate>\n") to:outFile ;
203                        format("\t\t\t\t\t\t</keyframe>\n") to:outFile ;
204                )
205        )
206       
207        -- track end
208        format("\t\t\t\t\t</keyframes>\n") to:outFile ;
209        format("\t\t\t\t</track>\n") to: outFile ;
210)
211
212-------------------------------------------------------------------------------------------------
213------------------------------------------- WRITE SKELETON --------------------------------------
214-------------------------------------------------------------------------------------------------
215
216-------------------------------------
217-- List of bones in the hierarchy
218-------------------------------------
219global BonesList=#()
220global RootsList=#()
221
222-------------------------------------
223-- helper functions to build skeleton
224-------------------------------------
225
226-----------------------------------------------------------------
227-- recursive function to build the list of bones for the skeleton
228-----------------------------------------------------------------
229function computeBList b sk phy exportHelpers =
230(
231        bname = b ;
232        bone = getNodeByName bname ;
233        if (findItem BonesList bname == 0) then
234                if (isKindOf bone BoneGeometry or iskindOf bone Biped_Object or (exportHelpers and (isPartOfModifier bone sk phy)) ) then
235                        append BonesList bname ;
236        childrenArray = bone.children ;
237        for i=1 to childrenArray.count do
238        (
239        if (isKindOf bone BoneGeometry or iskindOf bone Biped_Object or (exportHelpers and (isPartOfModifier bone sk phy))) then
240                        computeBList (replaceSpaces childrenArray[i].name) sk phy exportHelpers;
241        )
242)
243
244function addHelpersToHierarchy phy sk =
245(
246        if (sk != undefined) then
247        (
248                for i=1 to (skinOps.GetNumberBones sk) do
249                (
250                        bname = skinOps.GetBoneName sk i 1 ;
251                        replaceSpaces bname ;
252                        d = getNodeByName bname ;
253
254                        if (iskindof d helper) then
255                                append BonesList bname ;
256                )       
257        )
258        else if (phy != undefined) then
259        (
260                for i=1 to (physiqueOps.GetBoneCount $) do
261                (
262                        bname = (physiqueOps.GetBones $)[i].name;
263                        replaceSpaces bname ;
264                        d = getNodeByName bname ;
265               
266                        if (iskindof d helper) then
267                                append BonesList bname ;
268                )       
269        )
270)
271
272-----------------------------------------------------------------
273-- find the root(s) of the rhierarchy
274-----------------------------------------------------------------
275function getHierarchyRoots phy sk exportHelpers =
276(
277        local rootstab=#();
278       
279        if (sk != undefined) then
280        (
281                for i=1 to (skinOps.GetNumberBones sk) do
282                (
283                        bname= skinOps.GetBoneName sk i 1 ;
284                        replaceSpaces bname ;
285                        d = getNodeByName bname ;
286               
287                        while (d.parent!=undefined and (iskindof d.parent BoneGeometry or iskindOf d.parent Biped_Object or (exportHelpers and (isPartOfModifier d.parent sk phy)) )) do
288                        (
289                                d = d.parent
290                        )
291                        trouve = 0;
292                        --format("new potential root bone \"%\"\n") (replaceSpaces d.name) ;
293                        for j=1 to rootstab.count do
294                        (
295                                if (rootstab[j]!=undefined and (rootstab[j]==(replaceSpaces d.name)))then
296                                (
297                                        trouve = 1;
298                                        exit;
299                                )
300                        )
301                        if trouve==0 then
302                        (
303                                if (iskindof d BoneGeometry or iskindOf d Biped_Object or (exportHelpers and (isPartOfModifier d sk phy)) ) then
304                                (
305                                        if (not g_MAX) then
306                                                format("new root bone \"%\"\n") (replaceSpaces d.name) ;
307                                        rootstab[rootstab.count+1] = (replaceSpaces d.name) ;
308                                )
309                        )
310                )
311        )
312        else if (phy != undefined) then         -- physique modifier
313        (
314                for i=1 to (physiqueOps.GetBoneCount $) do
315                (
316                        bname = (physiqueOps.GetBones $)[i].name;
317                        replaceSpaces bname ;
318                        d = getNodeByName bname ;
319               
320                        while (d.parent!=undefined and (iskindof d.parent BoneGeometry or iskindOf d.parent Biped_Object  or (exportHelpers and (isPartOfModifier d.parent sk phy)) )) do
321                        (
322                                d = d.parent
323                        )
324                        trouve = 0;
325                        --format("new potential root bone \"%\"\n") (replaceSpaces d.name) ;
326                        for j=1 to rootstab.count do
327                        (
328                                if (rootstab[j]!=undefined and (rootstab[j]==(replaceSpaces d.name)))then
329                                (
330                                        trouve = 1;
331                                        exit;
332                                )
333                        )
334                        if trouve==0 then
335                        (
336                                if (iskindof d BoneGeometry or iskindOf d Biped_Object or (exportHelpers and (isPartOfModifier d sk phy))) then
337                                (
338                                        if (not g_MAX) then
339                                                format("new root bone \"%\"\n") (replaceSpaces d.name) ;
340                                        rootstab[rootstab.count+1] = (replaceSpaces d.name) ;
341                                )
342                        )
343                )
344        )
345       
346        rootstab;
347)
348
349-----------------------------------------------------------------
350-- function to build the list of bones for the skeleton
351-----------------------------------------------------------------
352function computeBonesList phy sk exportHelpers =
353(
354        RootsList = getHierarchyRoots phy sk exportHelpers;     -- find the roots of the current hierarchy
355        print RootsList;
356        for b in RootsList do
357        (
358                computeBList b sk phy exportHelpers;
359        )
360       
361        -- add the nodes that are parts of the skin (or physique) modifier but are neither biped_object nor standard bones
362        -- only helpers (Point, Dummy) at the moment...
363        -- addHelpersToHierarchy phy sk ;
364)
365
366------------------
367-- write <bones />
368------------------
369function writeB bone_name id scale flipYZ outFile =
370(
371        -- gets bone acording to the parameter boneId
372        bname = bone_name ;
373        replaceSpaces bname;
374        d = getNodeByName bname ;
375       
376        -- gets initial transform at frame 0f
377        format("\t\t<bone id=\"%\" name=\"%\">\n") (id-1) bname to:outFile ;
378
379        slidertime = 0f ;
380        Tform = d.transform ;
381        if (not isRootUniversal2 d) then (
382                mparent = d.parent.transform ;
383                Tform = Tform*inverse(mparent) ;
384        )
385       
386        Tform.pos = Tform.pos * scale ;
387               
388        if ((isRootUniversal2 d) and flipYZ) then (
389                if (not g_MAX) then
390                        format "- Flipping root... \n" ;
391                Tform = flipYZTransform Tform ;
392        )
393       
394        pos = Tform.pos ;
395        --rot = Tform.rotation as angleaxis ;
396        --angle = - degToRad (rot.angle) ; -- don't know why there must be this minus :((((((
397        rot = toAngleAxis Tform.rotation ;
398        angle = - rot.angle ;
399               
400        --              if (abs(pos.x)<1e-5) then pos.x = 0 ;
401        --              if (abs(pos.y)<1e-5) then pos.y = 0 ;
402        --              if (abs(pos.z)<1e-5) then pos.z = 0 ;
403       
404        -- Only object.transform was taken into account, but when mirror is applied
405    -- object.scale is modified and become [-1,-1,-1] that's why we do what follows:
406        if ((d.parent != undefined) and (hasproperty d.parent "scale")) then (
407        pos = pos * d.parent.scale ;
408    )
409                               
410        format("\t\t\t<position x=\"%\" y=\"%\" z=\"%\" />\n") pos.x pos.y pos.z to:outFile ;
411    format("\t\t\t<rotation angle=\"%\">\n") angle to:outFile ;
412    format("\t\t\t\t<axis x=\"%\" y=\"%\" z=\"%\" />\n") rot.axis.x rot.axis.y rot.axis.z to:outFile ;
413        format("\t\t\t</rotation>\n") to:outFile ;
414        format("\t\t</bone>\n") to:outFile ;
415)
416
417-----------------------------
418-- write Bones (using writeB)
419-----------------------------
420function writeBones phy sk scale flipYZ exportHelpers outFile =
421(
422        local i ;
423       
424        OgreExportObject.exportProgress.value = 0;
425
426        if (BonesList.count == 0) then
427                computeBonesList phy sk exportHelpers;
428       
429        format("\t<bones>\n") to:outFile;
430       
431        i = 0 ;
432       
433        for i=1 to BonesList.count do
434        (
435                OgreExportObject.exportProgress.value = (100.0*i/BonesList.count);
436
437                writeB BonesList[i] i scale flipYZ outFile ;
438        )       
439       
440        format("\t</bones>\n") to:outFile;
441       
442        OgreExportObject.exportProgress.value = 100;
443)
444
445--------------------------
446-- write <bonehierarchy />
447--------------------------
448function writeH b outFile =
449(
450        if (not isRootUniversal2 b) then
451        (
452                p = b.parent ;
453                format("\t\t<boneparent bone=\"%\" parent=\"%\" />\n") (replaceSpaces b.name) (replaceSpaces p.name) to:outFile ;
454        )
455)
456
457function writeHierarchy outFile =
458(
459        OgreExportObject.exportProgress.value = 0;
460
461        local bname,pelvis
462        format("\t<bonehierarchy>\n") to:outFile ;
463
464        for i=1 to BonesList.count do
465        (
466                OgreExportObject.exportProgress.value = (100.0*i/BonesList.count);
467
468                b = getNodeByName BonesList[i] ;
469                writeH b outFile ;     
470        )
471
472        format("\t</bonehierarchy>\n") to:outFile ;
473       
474        OgreExportObject.exportProgress.value = 100;
475)
476
477-----------------------
478-- write <animations />
479-----------------------
480function writeAnim Anims samplerate IKsamplerate scale flipYZ outFile =
481(
482        local i,n ;
483       
484        OgreExportObject.exportProgress.value = 0;
485       
486        format("\t<animations>\n") to: outFile ;
487       
488        for anm=1 to Anims.names.count do
489        (
490            format("\t\t<animation name=\"%\" length=\"%\">\n") Anims.names[anm] Anims.lengths[anm] to:outFile ;
491                format("\t\t\t<tracks>\n") to:outFile
492               
493                n = BonesList.count ;
494                for i = 1 to n do
495                (
496                        OgreExportObject.exportProgress.value = (100.0*i/BonesList.count)/Anims.names.count;
497
498                        writeTrack BonesList[i] i Anims.startframes[anm] Anims.endframes[anm] samplerate IKsamplerate Anims.lengths[anm] scale flipYZ outFile ;
499                )
500       
501                format("\t\t\t</tracks>\n") to:outFile                                 
502                format("\t\t</animation>\n") to: outFile ;
503        )
504       
505        format("\t</animations>\n") to: outFile ;
506
507        OgreExportObject.exportProgress.value = 100;
508)
509
510-------------------------------------------------------------
511-- write <skeleton /> main function
512-- write the animation in the file out_name + ".skeleton.xml"
513-- between the frame firstFrame and lastFrame
514-- and scale time according to length
515-------------------------------------------------------------
516
517function writeSkeleton pmesh exportOptions Anims out_name =
518(
519        local sk,n,keys,initialKeys,messages,phy ;
520       
521        sk = getSkin pmesh ;
522        phy = getPhysique pmesh ;
523       
524        if (sk == undefined and phy == undefined) then
525        (
526                MessageBox "There is no skin or physique modifier for this object" ;
527                return false;
528        )
529        else
530        (       
531                -- in order to perform, skin should be opened
532                max modify mode ;
533                if (sk != undefined) then
534                        modPanel.setCurrentObject pmesh.modifiers[#Skin] ;
535                else -- physique
536                        modPanel.setCurrentObject pmesh.modifiers[#Physique] ;
537
538                if (not g_MAX) then
539                (
540                        format "------------------------------------------\n"
541                        format "------ OGRE skeleton Exporter Log   ------\n"
542                        format "------------------------------------------\n"
543                       
544                        format "Exporter options :\n"
545                        for i=1 to Anims.names.count do
546                                format "Anim % - firstFrame: % - lastFrame: %\n" Anims.names[i] Anims.startframes[i] Anims.endframes[i] ;
547                        -- creates the output file
548                        outFile = createfile (out_name + ".skeleton.xml") ;
549                )
550                else
551                (
552                        if (g_MAX_use_listener) then
553                                format("<ogrestartfile>%</ogrestartfile><ogrestartdata>\n") (outName + ".skeleton.xml");
554                        outFile = listener;
555                )
556       
557                -- writes header
558                format("<skeleton>\n") to:outFile ;     
559       
560                if (not g_MAX) then
561                        format "Writing bones :\n" ;
562                writeBones phy sk exportOptions.scale exportOptions.flipYZ exportOptions.exportHelpers outFile ;
563
564                if (not g_MAX) then
565                        format "Writing bone hierarchy.\n" ;
566                writeHierarchy outFile ;
567
568                if (not g_MAX) then
569                        format "Writing bone tracks.\n" ;
570                writeAnim Anims exportOptions.sampleRate exportOptions.ikSampleRate exportOptions.scale exportOptions.flipYZ outFile ;
571
572                -- ecriture, fin des balises
573                format("</skeleton>\n") to: outFile ;
574                               
575                if (not g_MAX) then
576                (
577                        format "------------------------------------------\n"
578                        format "----------          END          ---------\n"
579                        format "------------------------------------------\n"
580               
581                        close outFile ;
582                )
583                else
584                (
585                        if (g_MAX_use_listener) then
586                                format("</ogrestartdata>\n") to: outFile;
587                )
588               
589                messageBox "Exporting skeleton successful !"
590                return true;
591        )
592)
593
594
595
Note: See TracBrowser for help on using the repository browser.