0eea95bcc9350a8af2a26c9b732b590fdee1cc4e
[blender.git] / release / scripts / DirectX8Exporter.py
1 #!BPY
2
3 """ Registration info for Blender menus:
4 Name: 'DirectX8 (.x)...'
5 Blender: 234
6 Group: 'Export'
7 Submenu: 'Export to DX8 file format' export
8 Submenu: 'How to use this exporter?' help
9 Tip: 'Export to DirectX8 text file format'
10 """
11
12 __author__ = "Arben (Ben) Omari"
13 __url__ = ("blender", "elysiun", "Author's site, http://www.omariben.too.it")
14 __version__ = "1.0"
15
16 __bpydoc__ = """\
17 This script exports a Blender mesh with armature to DirectX 8's text file
18 format.
19
20 Usage:
21
22 1) There should be only one mesh and one armature in the scene;
23
24 2) Before parenting set:<br>
25    a) Armature and mesh must have the same origin location
26 (in the 3d View press N (menu Object->"Transform Properties") for both and set
27 same LocX, LocY and LocZ);<br>
28    b) Armature and mesh must have the same rotation
29 (select them and press Ctrl + A);
30
31 3) Set the number of the animation frames to export;
32
33 4) Read warnings (if any) in console.
34
35 Notes:<br>
36     Check author's site or the elYsiun forum for a new beta version of the
37 DX exporter.
38 """
39
40
41 # $Id$
42 #
43 # DirectX8Exporter.py version 1.0
44 # Copyright (C) 2003  Arben OMARI -- omariarben@everyday.com 
45 #
46 # This program is free software; you can redistribute it and/or modify
47 # it under the terms of the GNU General Public License as published by
48 # the Free Software Foundation; either version 2 of the License, or
49 # (at your option) any later version.
50 #
51 # This program is distributed in the hope that it will be useful,
52 # but WITHOUT ANY WARRANTY; without even the implied warranty of
53 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
54 # GNU General Public License for more details.
55
56 # This script export meshes created with Blender in DirectX8 file format
57 # it exports meshes,armatures,materials,normals,texturecoords and animations
58
59 # Grab the latest version here :www.omariben.too.it
60
61 import Blender
62 from Blender import Types, Object, NMesh, Material,Armature
63 from Blender.Mathutils import *
64
65 global new_bon,mat_flip,index_list
66 index_list = []
67 new_bon = {}
68 mat_flip = Matrix([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1])
69
70 def draw():
71         
72         # clearing screen
73         Blender.BGL.glClearColor(0.5, 0.5, 0.5, 1)
74         Blender.BGL.glColor3f(1.,1.,1.)
75         Blender.BGL.glClear(Blender.BGL.GL_COLOR_BUFFER_BIT)
76         
77         # Buttons
78         Blender.Draw.Button("Exit", 1, 10, 40, 100, 25)
79
80         #Text
81         Blender.BGL.glColor3f(1, 1, 1)
82         Blender.BGL.glRasterPos2d(10, 310)
83         Blender.Draw.Text("1.Only one mesh and one armature in the scene")
84         Blender.BGL.glRasterPos2d(10, 290)
85         Blender.Draw.Text("2.Before parenting set:")
86  
87         
88         
89         Blender.BGL.glRasterPos2d(10, 270)
90         Blender.Draw.Text("     a)Armature and mesh must have the same origin location")
91         Blender.BGL.glRasterPos2d(10, 255)
92         Blender.Draw.Text("       (press N for both and set the same LocX,LocY and LocZ)")
93         Blender.BGL.glRasterPos2d(10, 230)
94         Blender.Draw.Text("      b)Armature and mesh must have the same to rotation")
95         Blender.BGL.glRasterPos2d(10, 215)
96         Blender.Draw.Text("        (select them and press Ctrl + A)")
97         Blender.BGL.glRasterPos2d(10, 195)
98         Blender.Draw.Text("3.Set the number of the animation frames to export ")
99         Blender.BGL.glRasterPos2d(10, 175)
100         Blender.Draw.Text("5.Read warnings in console(if any)")
101         
102         
103
104 def event(evt, val):
105         if evt == Blender.Draw.ESCKEY and not val: Blender.Draw.Exit()
106
107 def bevent(evt):
108         
109         if evt == 1: Blender.Draw.Exit()
110         
111                 
112
113 #***********************************************
114 #***********************************************
115 #                EXPORTER
116 #***********************************************
117 #***********************************************
118
119 class xExport:
120         def __init__(self, filename):
121                 self.file = open(filename, "w")
122
123 #*********************************************************************************************************************************************
124         #***********************************************
125         #Export Animation
126         #***********************************************
127         def exportMesh(self,arm,arm_ob,tex):
128                 
129                 for name in Object.Get():
130                         obj = name.getData()
131                         if type(obj) == Types.NMeshType :               
132                                 self.writeMeshcoord(name, obj,arm_ob)
133                                 self.writeMeshMaterialList(name, obj, tex)
134                                 self.writeMeshNormals(name, obj)
135                                 self.writeMeshTextureCoords(name, obj)
136                                 self.writeSkinWeights(arm,obj)
137                                 self.file.write(" }\n")
138                                 self.file.write("}\n")
139                                 self.writeAnimation(name, obj,arm)
140         #***********************************************
141         #Export Root Bone
142         #***********************************************
143         def writeRootBone(self):
144                 global new_bon,mat_flip
145                 space = 0
146                 tex = []
147                 print "exporting ..."
148                 self.writeHeader()
149                 for name in Object.Get():
150                         obj = name.getData()
151                         if type(obj) == Types.NMeshType :
152                                 self.writeTextures(name, tex)
153                         arm = name.getData()
154                         if type(arm) == Types.ArmatureType :
155                                 Blender.Set('curframe',1)
156                                 am_ob = Object.Get(name.name)
157                                 mat_ob = mat_flip * am_ob.getMatrix()
158                                 self.writeArmFrames(mat_ob, "RootFrame", 0)
159                                 root_bon = arm.getBones()
160                                 mat_r = self.writeCombineMatrix(root_bon[0])  
161                                 name_r = root_bon[0].getName()
162                                 new_bon[name_r] = len(root_bon[0].getChildren())
163                                 self.writeArmFrames(mat_r, name_r, 1)
164                                 self.writeListOfChildrens(root_bon[0],2,arm)
165                                 self.file.write("}\n")
166                                 self.exportMesh(arm,am_ob, tex)
167                 self.writeEnd()
168         #***********************************************
169         #Export Children Bones
170         #***********************************************
171         def writeListOfChildrens(self,bon,space,arm):
172                 global  new_bon
173                 bon_c = bon.getChildren()
174                 Blender.Set('curframe',1)
175                 for n in range(len(bon_c)):
176                         name_h = bon_c[n].getName()
177                         chi_h = bon_c[n].getChildren()
178                         new_bon[name_h] = len(chi_h)
179
180                 if bon_c == [] :
181                         self.CloseBrackets(bon, new_bon, space, arm.getBones()[0])
182                 
183                 for nch in range(len(bon_c)):
184                         mat = self.writeCombineMatrix(bon_c[nch])
185                         name_ch = bon_c[nch].getName()
186                         self.writeArmFrames(mat, name_ch,space)
187                         self.findChildrens(bon_c[nch],space,arm)
188                 
189                 
190         #***********************************************
191         #Create Children structure
192         #***********************************************
193         def CloseBrackets(self, bon, new_bon, space, root_bon):
194                 tab = "  "
195                 self.file.write("%s" % (tab * (space -1)))
196                 self.file.write("}\n")
197                 while bon.hasParent():
198                         if new_bon[bon.getName()] == 0:
199                                 pare = bon.getParent()
200                                 name_p = pare.getName()
201                                 if new_bon[name_p] > 0:
202                                         new_bon[name_p] = new_bon[name_p] - 1
203                                 if new_bon[name_p] == 0 and pare != root_bon:
204                                         self.file.write("%s" % (tab * (space-2)))
205                                         self.file.write("}\n")
206                                 space = space - 1
207                                 bon = pare
208                         else:
209                                 break
210                 
211                         
212         #***********************************************
213         #Create Children structure
214         #***********************************************
215         def findChildrens(self,bon_c,space,arm):
216                 bon_cc = bon_c
217                 space += 1
218                 self.writeListOfChildrens(bon_cc,space,arm)
219         
220         
221         #***********************************************
222         #Offset Matrix
223         #***********************************************
224         def writeMatrixOffset(self,bon):
225                 Blender.Set('curframe',1)
226                 mat_b = bon.getRestMatrix()       
227                 mat_b.invert() 
228                 return mat_b
229
230
231         
232
233         #***********************************************
234         #Combine Matrix
235         #***********************************************
236         def writeCombineMatrix(self,bon):
237                 Blender.Set('curframe',1)
238                 mat_b = bon.getRestMatrix()     
239                 if bon.hasParent():
240                         pare = bon.getParent()
241                         mat_p = pare.getRestMatrix()
242                 else :
243                         mat_p = Matrix([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1])
244                 mat_p.invert()
245                 mat_rb = mat_b * mat_p
246                 return mat_rb
247
248         #***********************************************
249         #Combine Matrix
250         #***********************************************
251         def writeCombineAnimMatrix(self,bon):
252                 
253                 mat_b = bon.getRestMatrix()     
254                 if bon.hasParent():
255                         pare = bon.getParent()
256                         mat_p = pare.getRestMatrix()
257                 else :
258                         mat_p = Matrix([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1])
259                 mat_p.invert()
260                 mat_rb = mat_b * mat_p
261                 return mat_rb
262
263
264 #*********************************************************************************************************************************************
265         #***********************************************
266         #Write SkinWeights
267         #***********************************************
268         def writeSkinWeights(self, arm, mesh):
269                 global index_list
270                 
271                 Blender.Set('curframe',1)
272                 self.file.write("  XSkinMeshHeader {\n")
273                 max_infl = 0
274                 for bo in arm.getBones() :
275                         name = bo.getName() 
276                         try :
277                                 vertx_list = mesh.getVertsFromGroup(name,1)
278                                 for inde in vertx_list :
279                                         vert_infl = mesh.getVertexInfluences(inde[0])
280                                         ln_infl = len(vert_infl)
281                                         if ln_infl > max_infl :
282                                                 max_infl = ln_infl
283                                 
284                         except:
285                                 pass
286                 
287                 self.file.write("    %s; \n" % (max_infl))
288                 self.file.write("    %s; \n" % (max_infl * 3))
289                 self.file.write("    %s; \n" % (len(arm.getBones())))
290                 self.file.write("  }\n")
291                 
292                 for bo in arm.getBones() :
293                         bo_list = []
294                         weight_list = []
295                         name = bo.getName() 
296                         try :
297                                 vert_list = mesh.getVertsFromGroup(name,1)
298                                 le = 0
299                                 for indx in vert_list:
300                                         ver_infl = mesh.getVertexInfluences(indx[0])
301                                         len_infl = float(len(ver_infl))
302                                         infl = 1 / len_infl
303                                         i = -1
304                                         for el in index_list :
305                                                 i += 1
306                                                 if el == indx[0] :
307                                                         le +=1
308                                                         bo_list.append(i)
309                                                         weight_list.append(infl)
310
311
312                                 self.file.write("  SkinWeights {\n")
313                                 self.file.write('    "%s"; \n' % (name))
314                                 self.file.write('     %s; \n' % (le))
315                                 count = 0
316                                 for ind in bo_list :
317                                         count += 1
318                                         if count == len(bo_list):
319                                                 self.file.write("    %s; \n" % (ind))
320                                         else :
321                                                 self.file.write("    %s, \n" % (ind))
322                                 cou = 0
323                                 for wegh in weight_list :
324                                         cou += 1
325                                         
326                                         if cou == len(weight_list):
327                                                 self.file.write("    %s; \n" % (round(wegh,6)))
328                                         else :
329                                                 self.file.write("    %s, \n" % (round(wegh,6)))
330
331                         
332                                 matx = self.writeMatrixOffset(bo)
333                         
334                                 self.writeOffsFrames(matx, name, 1)
335                         except :
336                                 pass
337                 self.file.write("  }\n")
338                 
339
340         #***********************************************
341         # Write Matrices
342         #***********************************************
343         def writeArmFrames(self, matx, name, space):
344                 tab = "  "
345                 self.file.write("%s" % (tab * space))
346                 self.file.write("Frame ")  
347                 self.file.write("%s {\n\n" % (name))
348                 self.file.write("%s" % (tab * space))
349                 self.file.write("  FrameTransformMatrix {\n")
350                 self.file.write("%s" % (tab * space))
351                 self.file.write("    %s,%s,%s,%s," %
352                                                         (round(matx[0][0],4),round(matx[0][1],4),round(matx[0][2],4),round(matx[0][3],4)))
353                 self.file.write("%s,%s,%s,%s," %
354                                                         (round(matx[1][0],4),round(matx[1][1],4),round(matx[1][2],4),round(matx[1][3],4)))      
355                 self.file.write("%s,%s,%s,%s," %
356                                                         (round(matx[2][0],4),round(matx[2][1],4),round(matx[2][2],4),round(matx[2][3],4)))
357                 self.file.write("%s,%s,%s,%s;;\n" %
358                                                         (round(matx[3][0],4),round(matx[3][1],4),round(matx[3][2],4),round(matx[3][3],6)))
359                 self.file.write("%s" % (tab * space))
360                 self.file.write("  }\n")
361         
362         #***********************************************
363         # Write Matrices
364         #***********************************************
365         def writeOffsFrames(self, matx, name, space):
366                 tab = "  "
367                 self.file.write("%s" % (tab * space))
368                 self.file.write("    %s,%s,%s,%s," %
369                                                         (round(matx[0][0],4),round(matx[0][1],4),round(matx[0][2],4),round(matx[0][3],4)))
370                 self.file.write("%s,%s,%s,%s," %
371                                                         (round(matx[1][0],4),round(matx[1][1],4),round(matx[1][2],4),round(matx[1][3],4)))      
372                 self.file.write("%s,%s,%s,%s," %
373                                                         (round(matx[2][0],4),round(matx[2][1],4),round(matx[2][2],4),round(matx[2][3],4)))
374                 self.file.write("%s,%s,%s,%s;;\n" %
375                                                         (round(matx[3][0],4),round(matx[3][1],4),round(matx[3][2],4),round(matx[3][3],6)))
376                 self.file.write("%s" % (tab * space))
377                 self.file.write("  }\n")
378         
379          
380 #*********************************************************************************************************************************************
381         
382         #***********************************************
383         #HEADER
384         #***********************************************  
385         def writeHeader(self):
386                 self.file.write("xof 0303txt 0032\n\n\n")
387                 self.file.write("template VertexDuplicationIndices { \n\
388  <b8d65549-d7c9-4995-89cf-53a9a8b031e3>\n\
389  DWORD nIndices;\n\
390  DWORD nOriginalVertices;\n\
391  array DWORD indices[nIndices];\n\
392 }\n\
393 template XSkinMeshHeader {\n\
394  <3cf169ce-ff7c-44ab-93c0-f78f62d172e2>\n\
395  WORD nMaxSkinWeightsPerVertex;\n\
396  WORD nMaxSkinWeightsPerFace;\n\
397  WORD nBones;\n\
398 }\n\
399 template SkinWeights {\n\
400  <6f0d123b-bad2-4167-a0d0-80224f25fabb>\n\
401  STRING transformNodeName;\n\
402  DWORD nWeights;\n\
403  array DWORD vertexIndices[nWeights];\n\
404  array float weights[nWeights];\n\
405  Matrix4x4 matrixOffset;\n\
406 }\n\n")
407                 
408         #***********************************************
409         #CLOSE FILE
410         #***********************************************
411         def writeEnd(self):
412                 self.file.close()
413                 print "... finished"
414
415
416         #***********************************************
417         #EXPORT TEXTURES
418         #***********************************************
419         def writeTextures(self,name, tex):
420                 mesh = name.data
421                 for face in mesh.faces:
422                         if face.image and face.image.name not in tex:
423                                 tex.append(face.image.name)
424                                 
425
426
427         #***********************************************
428         #EXPORT MESH DATA
429         #***********************************************
430         def writeMeshcoord(self, name, mesh,armat):
431                 global index_list
432                 #ROTATION
433                 mat_ob = name.getMatrix() 
434                 mat_ar = armat.getInverseMatrix()
435                 mat_f = mat_ob * mat_ar
436                 self.writeArmFrames(mat_f, "body", 1)
437
438                 self.file.write("Mesh {\n")    
439                 numfaces=len(mesh.faces)
440                 #VERTICES NUMBER
441                 numvert = 0
442                 for face in mesh.faces:
443                         numvert = numvert + len(face.v)
444                 self.file.write("%s;\n" % (numvert))
445                 #VERTICES COORDINATES
446                 counter = 0
447                 for face in mesh.faces:
448                         counter += 1
449                         for n in range(len(face.v)):
450                                 index_list.append(face.v[n].index)
451                                 self.file.write("%s; %s; %s;" % (face.v[n].co[0], face.v[n].co[1], face.v[n].co[2]))
452                                 if counter == numfaces :
453                                         if n == len(face.v)-1 :
454                                                 self.file.write(";\n")
455                                         else :
456                                                 self.file.write(",\n")
457                                 else :
458                                         self.file.write(",\n")
459
460                 #FACES NUMBER 
461                 self.file.write("%s;\n" % (numfaces))  
462                 #FACES INDEX
463                 numface=len(mesh.faces)
464                 coun,counter = 0, 0
465                 for face in mesh.faces :
466                         coun += 1
467                         if coun == numface:
468                                 if len(face.v) == 3:
469                                         self.file.write("3; %s, %s, %s;;\n" % (counter, counter + 2, counter + 1))
470                                         counter += 3
471                                 else :
472                                         self.file.write("4; %s, %s, %s, %s;;\n" % (counter, counter + 3, counter + 2, counter + 1))
473                                         counter += 4
474                         else:
475                                 
476                                 if len(face.v) == 3:
477                                         self.file.write("3; %s, %s, %s;,\n" % (counter, counter + 2, counter + 1))
478                                         counter += 3
479                                 else :
480                                         self.file.write("4; %s, %s, %s, %s;,\n" % (counter, counter + 3, counter + 2, counter + 1))
481                                         counter += 4
482                 
483
484                 
485         #***********************************************
486         #VERTEX DUPLICATION INDEX
487         #***********************************************
488         def writeVertDupInd(self, mesh):
489                 self.file.write("  VertexDuplicationIndices {\n")
490                 numvert = 0
491                 numfaces=len(mesh.faces)
492                 for face in mesh.faces:
493                         numvert = numvert + len(face.v)
494                 self.file.write("   %s;\n" % (numvert+len(mesh.verts)))
495                 self.file.write("   %s;\n" % (len(mesh.verts)))
496                 #VERTICES INDEX
497                 cou = 0
498                 for vert in mesh.verts:
499                         cou += 1
500                         self.file.write("   %s" % ((vert.index)))
501                         if cou == len(mesh.verts):
502                                 self.file.write(";\n")
503                         else:
504                                 self.file.write(",\n")
505
506                 counter = 0
507                 for face in mesh.faces:
508                         counter += 1
509                         if counter == numfaces:
510                                 if len(face.v) == 4:
511                                         self.file.write("   %s,\n" % ((face.v[0].index)))
512                                         self.file.write("   %s,\n" % ((face.v[1].index)))               
513                                         self.file.write("   %s,\n" % ((face.v[2].index)))
514                                         self.file.write("   %s;\n" % ((face.v[3].index)))
515                                 elif len(face.v) == 3 :
516                                         self.file.write("   %s,\n" % ((face.v[0].index)))
517                                         self.file.write("   %s,\n" % ((face.v[1].index)))               
518                                         self.file.write("   %s;\n" % ((face.v[2].index)))
519
520                         else :
521                                 if len(face.v) == 4:
522                                         self.file.write("   %s,\n" % ((face.v[0].index)))
523                                         self.file.write("   %s,\n" % ((face.v[1].index)))               
524                                         self.file.write("   %s,\n" % ((face.v[2].index)))
525                                         self.file.write("   %s,\n" % ((face.v[3].index)))
526                                 elif len(face.v) == 3 :
527                                         self.file.write("   %s,\n" % ((face.v[0].index)))
528                                         self.file.write("   %s,\n" % ((face.v[1].index)))               
529                                         self.file.write("   %s,\n" % ((face.v[2].index)))
530                                         
531                 self.file.write("    }\n")
532                 
533                 
534                 
535         #***********************************************
536         #MESH MATERIAL LIST
537         #***********************************************
538         def writeMeshMaterialList(self, name, obj, tex):
539                 self.file.write("  MeshMaterialList {\n")
540                 #HOW MANY MATERIALS ARE USED
541                 count = 0
542                 for mat in Material.Get():
543                         count+=1
544                 self.file.write("    %s;\n" % (len(tex) + count))
545                 #HOW MANY FACES IT HAS
546                 numfaces=len(obj.faces)
547                 self.file.write("    %s;\n" % (numfaces))
548                 ##MATERIALS INDEX FOR EVERY FACE
549                 counter = 0
550                 for face in obj.faces :
551                         counter += 1
552                         mater = face.materialIndex
553                         if counter == numfaces:
554                                 if face.image and face.image.name in tex :
555                                         self.file.write("    %s;;\n" % (tex.index(face.image.name) + count))
556                                 else :
557                                         self.file.write("    %s;;\n" % (mater))
558                         else :
559                                 if face.image and face.image.name in tex :
560                                         self.file.write("    %s,\n" % (tex.index(face.image.name) + count))
561                                 else :
562                                         self.file.write("    %s,\n" % (mater))
563                         
564                 ##MATERIAL NAME
565                 for mat in Material.Get():
566                         self.file.write("  Material")
567                         for a in range(0,len(mat.name)):
568                                 if mat.name[a] == ".":
569                                         print "WARNING:the material " + mat.name + " contains '.' within.Many viewers may refuse to read the exported file"
570                         self.file.write(" %s "% (mat.name))
571                         self.file.write("{\n")
572                         self.file.write("    %s; %s; %s;" % (mat.R, mat.G, mat.B))
573                         self.file.write("%s;;\n" % (mat.alpha))
574                         self.file.write("    %s;\n" % (mat.spec))
575                         self.file.write("    %s; %s; %s;;\n" % (mat.specR, mat.specG, mat.specB))
576                         self.file.write("    0.0; 0.0; 0.0;;\n")
577                         self.file.write("  }\n") 
578                 
579                 for mat in tex:
580                         self.file.write("  Material Mat")
581                         self.file.write("%s "% (len(tex)))
582                         self.file.write("{\n")
583                         self.file.write("    1.0; 1.0; 1.0; 1.0;;\n")
584                         self.file.write("    1.0;\n")
585                         self.file.write("    1.0; 1.0; 1.0;;\n")
586                         self.file.write("    0.0; 0.0; 0.0;;\n")
587                         self.file.write("  TextureFilename {\n")
588                         self.file.write('    "%s" ;'% (face.image.name))
589                         self.file.write("  }\n")
590                         self.file.write("  }\n") 
591                 self.file.write("    }\n")
592
593         #***********************************************
594         #MESH NORMALS
595         #***********************************************
596         def writeMeshNormals(self,name,mesh):
597                 self.file.write("  MeshNormals {\n")
598                 #VERTICES NUMBER
599                 numvert = 0
600                 for face in mesh.faces:
601                         numvert = numvert + len(face.v)
602                 self.file.write("%s;\n" % (numvert))
603                 numfaces=len(mesh.faces)
604                 
605                 #VERTICES NORMAL
606                 counter = 0
607                 for face in mesh.faces:
608                         counter += 1  
609                         for n in range(len(face.v)):
610                                 self.file.write("    %s; %s; %s;" % ((round(face.v[n].no[0],6)),(round(face.v[n].no[1],6)),(round(face.v[n].no[2],6))))
611                                 if counter == numfaces :
612                                         if n == len(face.v)-1 :
613                                                 self.file.write(";\n")
614                                         else :
615                                                 self.file.write(",\n")
616                                 else :
617                                         self.file.write(",\n")
618                 
619
620
621                 #FACES NUMBER 
622                 self.file.write("%s;\n" % (numfaces))  
623                 coun,counter = 0, 0
624                 for face in mesh.faces :
625                         coun += 1
626                         if coun == numfaces:
627                                 if len(face.v) == 3:
628                                         self.file.write("3; %s, %s, %s;;\n" % (counter, counter + 2, counter + 1))
629                                         counter += 3
630                                 else :
631                                         self.file.write("4; %s, %s, %s, %s;;\n" % (counter, counter + 3, counter + 2, counter + 1))
632                                         counter += 4
633                         else:
634                                 
635                                 if len(face.v) == 3:
636                                         self.file.write("3; %s, %s, %s;,\n" % (counter, counter + 2, counter + 1))
637                                         counter += 3
638                                 else :
639                                         self.file.write("4; %s, %s, %s, %s;,\n" % (counter, counter + 3, counter + 2, counter + 1))
640                                         counter += 4
641                 self.file.write("}\n")
642
643         #***********************************************
644         #MESH TEXTURE COORDS
645         #***********************************************
646         def writeMeshTextureCoords(self, name, mesh):
647                 if mesh.hasFaceUV():
648                         self.file.write("MeshTextureCoords {\n")
649                         #VERTICES NUMBER
650                         numvert = 0
651                         for face in mesh.faces:
652                                 numvert += len(face.v)
653                         self.file.write("%s;\n" % (numvert))
654                         #UV COORDS
655                         numfaces = len(mesh.faces)
656                         counter = -1
657                         co = 0
658                         for face in mesh.faces:
659                                 counter += 1
660                                 co += 1
661                                 for n in range(len(face.v)):
662                                         self.file.write("%s;%s;" % (mesh.faces[counter].uv[n][0], -mesh.faces[counter].uv[n][1]))
663                                         if co == numfaces :
664                                                 if n == len(face.v) - 1 :
665                                                         self.file.write(";\n")
666                                                 else :
667                                                         self.file.write(",\n")
668                                         else :
669                                                 self.file.write(",\n")
670
671                         self.file.write("}\n")
672 #***********************************************#***********************************************#***********************************************
673         #***********************************************
674         #FRAMES
675         #***********************************************
676         def writeFrames(self, matx):
677                 
678                 self.file.write("%s,%s,%s,%s," %
679                                                         (round(matx[0][0],4),round(matx[0][1],4),round(matx[0][2],4),round(matx[0][3],6)))
680                 self.file.write("%s,%s,%s,%s," %
681                                                         (round(matx[1][0],4),round(matx[1][1],4),round(matx[1][2],4),round(matx[1][3],6)))      
682                 self.file.write("%s,%s,%s,%s," %
683                                                         (round(matx[2][0],4),round(matx[2][1],4),round(matx[2][2],4),round(matx[2][3],6)))
684                 self.file.write("%s,%s,%s,%s;;" %
685                                                         (round(matx[3][0],4),round(matx[3][1],4),round(matx[3][2],4),round(matx[3][3],6)))
686                 
687                 
688                 
689                 
690         #***********************************************
691         #WRITE ANIMATION KEYS
692         #***********************************************
693         def writeAnimation(self, name, obj, arm):
694                 self.file.write("AnimationSet {\n")
695                 startFr = Blender.Get('staframe')
696                 endFr = Blender.Get('endframe')
697                 for bon in arm.getBones() :
698                         
699                         self.file.write(" Animation { \n")
700                         self.file.write("  {%s}\n" %(bon.getName()))
701                         self.file.write("  AnimationKey { \n")
702                         self.file.write("   4;\n")
703                         self.file.write("   %s; \n" % (endFr))
704
705                         self.file.write("   %s;" % (1))
706                         self.file.write("16;")
707                         mat = self.writeCombineMatrix(bon)
708                         self.writeFrames(mat)
709                         self.file.write(",\n")
710
711                         for fr in range(startFr+1,endFr + 1) :
712                                 self.file.write("   %s;" % (fr))
713                                 self.file.write("16;")
714                                 Blender.Set('curframe',fr)
715                                 
716                                 mat_new = self.writeCombineAnimMatrix(bon)
717                                 self.writeFrames(mat_new)
718                                 
719                                 if fr == endFr:
720                                         self.file.write(";\n")
721                                 else:
722                                         self.file.write(",\n")
723                         self.file.write("   }\n")
724                         self.file.write(" }\n")
725                         self.file.write("\n")
726                 self.file.write("}\n")
727                 
728 #***********************************************#***********************************************#***********************************************
729
730
731
732 #***********************************************
733 # MAIN
734 #***********************************************
735
736 def my_callback(filename):
737         if filename.find('.x', -2) <= 0: filename += '.x' 
738         xexport = xExport(filename)
739         xexport.writeRootBone()
740
741
742 arg = __script__['arg']
743 if arg == 'help':
744         Blender.Draw.Register(draw,event,bevent)
745 else:
746         fname = Blender.sys.makename(ext = ".x")
747         Blender.Window.FileSelector(my_callback, "Export DirectX8", fname)