source: OGRE/trunk/ogrenew/Tools/3dsmaxExport/scripts/ogre/lib/OgreSkeletonLib_skelfns.ms @ 657

Revision 657, 10.1 KB checked in by mattausch, 18 years ago (diff)

added ogre dependencies and patched ogre sources

Line 
1-----------------------------------------------------------------------------
2-- gets  keyframes from the controllers animation
3-----------------------------------------------------------------------------
4function getTimeList obj firstframe lastframe =
5(
6        local list,rotContr,posContr,  ;
7        list = #(firstframe) ;
8        list2 = #() ; -- this is the list which will be returned.
9       
10        -- Biped_Objects and Bones don't have the same properties
11       
12        -- Biped_Objets
13        if (isKindOf obj Biped_Object) then (
14                for e in obj.controller.keys do (
15                        t =e.time ;
16                        if (t>firstFrame and t<=lastFrame) then
17                                append list t ;
18                )
19        )
20        -- Bones       
21        else (
22                rotContr = obj.rotation.controller ;
23                posContr = obj.pos.controller ;
24               
25                for e in rotContr.keys do (
26                        t = e.time ;
27                        if (t>firstFrame and t<=lastFrame) then
28                                append list t ;
29                )
30                for e in posContr.keys do (
31                        t = e.time ;
32                        if (t>firstFrame and t<=lastFrame) then
33                                append list t ;
34                )       
35        )
36        -- if several keyframes have the same value, we keep just one
37        keepLoneValues list list2 ;
38        list2 ;
39)
40
41
42-----------------------------------------------------------------------------
43-- write <track />
44-- Selected keys belongs to [firstframe,lastFrame]
45-- time = (key.time - firstFrame)*length/(lastFrame-firstFrame)
46--   (e.g. first key has time 0.)
47-----------------------------------------------------------------------------
48
49function writeTrack sk boneId firstframe lastframe length scale flipYZ outFile=
50(
51        local angle,timef,i,bname,d,mref,mparent ;
52       
53        -- displays information in the maxscript listener
54        format "retrieving key information for % ...\n" (skinOps.GetBoneName sk boneId 1) ;
55       
56        -- gets bone acording to the parameter boneId
57        bname= skinOps.GetBoneName sk boneId 1 ;
58        replaceSpaces bname ;
59        d = execute ("$" + bname) ;
60       
61        -- gets keyframe list
62        timelist = getTimeList d firstframe lastframe ;
63       
64        -- track header
65        format("\t\t\t\t<track bone = \"%\">\n") (replaceSpaces d.name) to:outFile ;
66        format("\t\t\t\t\t<keyframes>\n") to:outFile ;
67       
68        -- gets initial transform at frame 0f
69        at time 0f (
70                initTform = d.transform ;
71                if (not isRoot d) then (
72                        mparent = d.parent.transform ;
73                        initTform = initTform*inverse(mparent) ;
74                )
75                else if (flipYZ) then (
76                        format " - flipping root bone track..." ;
77                        initTform = flipYZTransform initTform ;
78                )
79        )
80               
81        -- for each frame in the list
82        for i in timelist do
83        (
84                -- moves slider time and compute OGRE time
85                at time i (
86                        timef = ((float) (i-firstFrame)*length)/(lastframe - firstframe ) ;
87                       
88                -- First, rotation which depends on initial transformation
89                        Tform = d.transform ;
90                        -- if this is the root bone
91                        if (isRoot d) then (
92                                mparent = matrix3 1 ;
93                                -- if flipYZ == true
94                                if (flipYZ) then
95                                        Tform = flipYZTransform Tform ;
96                        )                       
97                        else
98                                mparent = d.parent.transform ;
99                       
100                        -- computes rotation
101                        mref = initTform*mparent ;     
102                        Tform = Tform*inverse(mref) ;
103                       
104                        -- rotation part is saved.
105                        rot = Tform.rotation as angleaxis ;
106                        angle = - degToRad (rot.angle) ; -- don't know why there must be this minus :((((((
107                       
108                -- Then, position which depends on parent                       
109                        Tform=d.transform ;
110                        Tform=Tform*inverse(mparent) ;
111                       
112                        -- if this is the root bone and flipYZ == true
113                        if (isRoot d and flipYZ) then (
114                                Tform = flipYZTransform Tform ;
115                        )
116                       
117                        -- substracts position of the initial transform
118                        Tform.pos -= initTform.pos ;
119                        Tform.pos = Tform.pos * scale ;
120                       
121                        pos = Tform.pos ;
122
123                               
124                        -- writes them !
125                        format("\t\t\t\t\t\t<keyframe time=\"%\">\n") timef to: outFile ;
126                        format("\t\t\t\t\t\t\t<translate x=\"%\" y=\"%\" z=\"%\" />\n") pos.x pos.y pos.z to: outFile ;
127                        format("\t\t\t\t\t\t\t<rotate angle=\"%\">\n") angle to:outFile ;
128                        format("\t\t\t\t\t\t\t\t<axis x=\"%\" y=\"%\" z=\"%\" />\n") (rot.axis.x) (rot.axis.y) (rot.axis.z) to:outFile ;
129                        format("\t\t\t\t\t\t\t</rotate>\n") to:outFile ;
130                        format("\t\t\t\t\t\t</keyframe>\n") to:outFile ;
131                )
132        )
133       
134        -- track end
135        format("\t\t\t\t\t</keyframes>\n") to:outFile ;
136        format("\t\t\t\t</track>\n") d.name to: outFile ;
137)
138
139
140-------------------------------------------------------------------------------------------------
141------------------------------------------- WRITE SKELETON --------------------------------------
142-------------------------------------------------------------------------------------------------
143
144-- Nota :
145-- A vertex 0 and a bone 0 are added because 3dsmax starts with vertex 1 and bone 1.
146
147
148------------------
149-- write <bones />
150------------------
151
152function writeB sk id scale flipYZ outFile =
153(
154        -- gets bone acording to the parameter boneId
155        bname= skinOps.GetBoneName sk id 1 ;
156        replaceSpaces bname ;
157        d = execute ("$" + bname) ;
158       
159        -- gets initial transform at frame 0f
160        format("\t\t<bone id=\"%\" name=\"%\">\n") id (replaceSpaces d.name) to:outFile ;
161       
162        slidertime = 0f ;
163        Tform = d.transform ;
164        if (not isRoot d) then (
165                mparent = d.parent.transform ;
166                Tform = Tform*inverse(mparent) ;
167        )
168       
169        Tform.pos = Tform.pos * scale ;
170               
171        if ((isRoot d) and flipYZ) then (
172                format "- Flipping root bone... \n" ;
173                Tform = flipYZTransform Tform ;
174        )
175       
176        pos = Tform.pos ;
177        rot = Tform.rotation as angleaxis ;
178        angle = - degToRad (rot.angle) ; -- don't know why there must be this minus :((((((
179       
180        format("\t\t\t<position x=\"%\" y=\"%\" z=\"%\" />\n") pos.x pos.y pos.z to:outFile ;
181    format("\t\t\t<rotation angle=\"%\">\n") angle to:outFile ;
182    format("\t\t\t\t<axis x=\"%\" y=\"%\" z=\"%\" />\n") rot.axis.x rot.axis.y rot.axis.z to:outFile ;
183        format("\t\t\t</rotation>\n") to:outFile ;
184        format("\t\t</bone>\n") to:outFile ;
185)
186-----------------------------
187-- write Bones (using writeB)
188-----------------------------
189
190function writeBones sk scale flipYZ outFile =
191(
192        local i ;
193       
194        format("\t<bones>\n") to:outFile;
195       
196        -- we create a virtual bone number 0.
197        format("\t\t<bone id=\"0\" name=\"zzwxy\">\n") to:outFile ;
198        format("\t\t\t<position x=\"0\" y=\"0\" z=\"0\" />\n") to:outFile ;
199    format("\t\t\t<rotation angle=\"0\">\n") to:outFile ;
200    format("\t\t\t\t<axis x=\"1\" y=\"0\" z=\"0\" />\n") to:outFile ;
201    format("\t\t\t</rotation>\n") to:outFile ;
202        format("\t\t</bone>\n") to:outFile ;
203        i = 0 ;
204        for i=1 to (skinOps.GetNumberBones sk) do
205        (
206                writeB sk i scale flipYZ outFile ;
207        )
208        format("\t</bones>\n") to:outFile;
209)
210
211-----------------------------------
212-- recursive fun to write hierarchy
213-----------------------------------
214
215function writeH b outFile =
216(
217        if ( b.parent != undefined and (isKindOf b.parent BoneGeometry or iskindOf b.parent Biped_Object)) then
218        (
219                p = b.parent ;
220                format("\t\t<boneparent bone=\"%\" parent=\"%\" />\n") (replaceSpaces b.name) (replaceSpaces p.name) to:outFile ;
221        )
222        childrenArray = b.children ;
223        for i=1 to childrenArray.count do
224        (
225        if (isKindOf b BoneGeometry or iskindOf b Biped_Object) then
226                        writeH childrenArray[i] outFile ;
227        )
228       
229)
230
231--------------------------
232-- write <bonehierarchy />
233--------------------------
234
235function writeHierarchy sk outFile =
236(
237        format("\t<bonehierarchy>\n") to:outFile ;
238        roots = getRoots sk ;
239       
240        -- ecriture de la track pour le bone 0.
241        format("\t\t<boneparent bone=\"zzwxy\" parent=\"%\" />\n") roots[1].name to:outFile ;
242        for b in roots do
243        (
244                writeH b outFile;
245        )
246        format("\t</bonehierarchy>\n") to:outFile ;
247)
248
249-----------------------
250-- write <animations />
251-----------------------
252function writeAnim sk firstFrame lastFrame length scale flipYZ name outFile =
253(
254        local i,n ;
255       
256        format("\t<animations>\n") to: outFile ;
257    format("\t\t<animation name=\"%\" length=\"%\">\n") name length to:outFile ;
258        format("\t\t\t<tracks>\n") to:outFile
259       
260        -- ecriture track 0
261        format("\t\t\t\t<track bone = \"zzwxy\">\n") to: outFile ;
262        format("\t\t\t\t\t<keyframes>\n") to:outFile ;
263        format("\t\t\t\t\t\t<keyframe  time=\"0\">\n") to:outFile ;
264        format("\t\t\t\t\t\t\t<translate x=\"0\" y=\"0\" z=\"0\" />\n") to: outFile ;
265        format("\t\t\t\t\t\t\t<rotate angle=\"0\">\n")  to:outFile ;
266        format("\t\t\t\t\t\t\t\t<axis x=\"1\" y=\"0\" z=\"0\" />\n")  to:outFile ;
267        format("\t\t\t\t\t\t\t</rotate>\n") to:outFile ;
268        format("\t\t\t\t\t\t</keyframe>\n") to:outFile ;
269        format("\t\t\t\t\t</keyframes>\n") to:outFile ;
270        format("\t\t\t\t</track>\n") to: outFile ;
271       
272        n = skinOps.GetNumberBones sk ;
273        liste = #(0,20,30,40) ;
274        for i = 1 to n do
275                writeTrack sk i firstframe lastframe length scale flipYZ outFile ;
276
277        format("\t\t\t</tracks>\n") to:outFile                                 
278        format("\t\t</animation>\n") to: outFile ;
279        format("\t</animations>\n") to: outFile ;
280)
281
282-------------------------------------------------------------
283-- write <skeleton /> main function
284-- write the animation in the file out_name + ".skeleton.xml"
285-- between the frame firstFrame and lastFrame
286-- and scale time according to length
287-------------------------------------------------------------
288
289function writeSkeleton pmesh exportOptions out_name =
290(
291        local sk,n,keys,initialKeys,messages ;
292        sk = getSkin pmesh ;
293       
294        if (sk == undefined) then
295        (
296                MessageBox "There is no skin modifier for this object" ;
297        )
298        else
299        (       
300                -- in order to perform, skin should be opened
301                max modify mode ;
302                modPanel.setCurrentObject pmesh.modifiers[#Skin] ;
303               
304                        format "------------------------------------------\n"
305                        format "------ OGRE skeleton Exporter Log   ------\n"
306                        format "------------------------------------------\n"
307               
308                        format "Exporter options :\n"
309                        format "- firstFrame: % \n- lastFrame: %\n" exportOptions.firstFrame exportOptions.lastFrame ;
310                        -- creates the output file
311                        outFile = createfile (out_name + ".skeleton.xml") ;
312
313                                -- writes header
314                                format("<skeleton>\n") to:outFile ;     
315       
316                                format "Writing bones :\n" ;
317                                writeBones sk exportOptions.scale exportOptions.flipYZ outFile ;
318                                format "Writing bone hierarchy.\n" ;
319                                writeHierarchy sk outFile ;
320                                format "Writing bone tracks.\n" ;
321                                writeAnim sk exportOptions.firstFrame exportOptions.lastFrame exportOptions.length exportOptions.scale exportOptions.flipYZ exportOptions.animName outFile ;
322
323                                -- ecriture, fin des balises
324                                format("</skeleton>\n") to: outFile ;
325                               
326                        format "------------------------------------------\n"
327                        format "----------          END          ---------\n"
328                        format "------------------------------------------\n"
329               
330                                close outFile ;
331                                messageBox "Exporting skeleton successful !"
332        )
333       
334)
335
336
337
Note: See TracBrowser for help on using the repository browser.