Scripts:
[blender.git] / release / scripts / DirectX8Exporter.py
1 #!BPY
2
3 """ Registration info for Blender menus:
4 Name: 'DirectX(.x)...'
5 Blender: 240
6 Group: 'Export'
7 Submenu: 'Export all the scene' export
8 Submenu: 'Export selected obj' exportsel
9 Tip: 'Export to DirectX text file format format.'
10 """
11 __author__ = "Arben (Ben) Omari"
12 __url__ = ("blender", "elysiun", "Author's site, http://www.omariben.too.it")
13 __version__ = "2.0"
14
15 __bpydoc__ = """\
16 This script exports a Blender mesh with armature to DirectX 8's text file
17 format.
18
19 Notes:<br>
20     Check author's site or the elYsiun forum for a new beta version of the
21 DX exporter.
22 """
23 # DirectXExporter.py version 2.0
24 # Copyright (C) 2006  Arben OMARI -- omariarben@everyday.com 
25 #
26 # This program is free software; you can redistribute it and/or modify
27 # it under the terms of the GNU General Public License as published by
28 # the Free Software Foundation; either version 2 of the License, or
29 # (at your option) any later version.
30 #
31 # This program is distributed in the hope that it will be useful,
32 # but WITHOUT ANY WARRANTY; without even the implied warranty of
33 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
34 # GNU General Public License for more details.
35
36 # This script export meshes created with Blender in DirectX8 file format
37 # it exports meshes,armatures,materials,normals,texturecoords and animations
38
39 # Grab the latest version here :www.omariben.too.it
40
41 import Blender
42 from Blender import Types, Object, NMesh, Material,Armature
43 from Blender.Mathutils import *
44 import math
45
46 global mat_flip,index_list,space,bone_list,mat_dict
47 bone_list =[]
48 index_list = []
49 mat_dict = {}
50 space = 0
51 ANIM = 1
52 NORMAL = 1
53 TEXCOORDS = 1
54 TEXTURE = 1
55 mat_flip = Matrix([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1])
56                 
57
58 #***********************************************
59 #***********************************************
60 #                EXPORTER
61 #***********************************************
62 #***********************************************
63
64 class xExport:
65         def __init__(self, filename):
66                 self.file = open(filename, "w")
67
68 #*********************************************************************************************************************************************
69         #***********************************************
70         #Select Scene objects
71         #***********************************************
72         def SelectObjs(self):
73                 global chld_obj
74                 print "exporting..."
75                 self.writeHeader()
76                 for obj in Object.Get():
77                         mesh = obj.getData()
78                         if type(mesh) == Types.NMeshType :
79                                 chld_obj = obj.getParent()
80                                 if chld_obj :
81                                         dt_chld_obj = chld_obj.getData()
82                                         if type(dt_chld_obj) == Types.ArmatureType :
83                                                 self.writeRootBone(chld_obj, obj)
84                                         
85                                 else :
86                                         self.exportMesh(obj)
87                 self.file.write("AnimationSet {\n")
88                 for obj in Object.Get():
89                         mesh = obj.getData()
90                         if type(mesh) == Types.NMeshType :
91                                 ip_list = obj.getIpo()
92                                 if ip_list != None :
93                                         self.writeAnimationObj(obj)
94                         elif type(mesh) == Types.ArmatureType :
95                                 act_list = obj.getAction()
96                                 if act_list != None :
97                                         self.writeAnimation(obj)
98                                 ip_list = obj.getIpo()
99                                 if ip_list != None :
100                                         self.writeAnimationObjArm(obj)
101                 self.file.write("}\n")
102                 self.writeEnd()
103         #***********************************************
104         #Export Mesh without Armature
105         #***********************************************
106         def exportMesh(self, obj):
107                 tex = []
108                 mesh = obj.getData()
109                 self.writeTextures(obj, tex)            
110                 self.writeMeshcoord(obj, mesh)
111                 self.writeMeshMaterialList(obj, mesh, tex)
112                 self.writeMeshNormals(obj, mesh)
113                 self.writeMeshTextureCoords(obj, mesh)
114                 self.file.write(" }\n")
115                 self.file.write("}\n")
116                 
117                                         
118         #***********************************************
119         #Export the Selected Mesh
120         #***********************************************
121         def exportSelMesh(self):
122                 print "exporting ..."
123                 self.writeHeader()
124                 tex = []
125                 obj = Object.GetSelected()[0]
126                 mesh = obj.getData()
127                 if type(mesh) == Types.NMeshType :
128                         self.writeTextures(obj, tex)            
129                         self.writeMeshcoord(obj, mesh)
130                         self.writeMeshMaterialList(obj, mesh, tex)
131                         self.writeMeshNormals(obj, mesh)
132                         self.writeMeshTextureCoords(obj, mesh)
133                         self.file.write(" }\n")
134                         self.file.write("}\n")
135                         ip_list = obj.getIpo()
136                         if ip_list != None :
137                                 self.file.write("AnimationSet {\n")
138                                 self.writeAnimationObj(obj)
139                                 self.file.write("}\n")
140                         print "exporting ..."
141                 else :
142                         print "The selected object is not a mesh"
143                 print "...finished"
144         #***********************************************
145         #Export Mesh with Armature
146         #***********************************************
147         def exportMeshArm(self,arm,arm_ob,ch_obj):
148                 tex = []
149                 mesh = ch_obj.getData()
150                 self.writeTextures(ch_obj, tex)         
151                 self.writeMeshcoordArm(ch_obj, mesh,arm_ob)
152                 self.writeMeshMaterialList(ch_obj, mesh, tex)
153                 self.writeMeshNormals(ch_obj, mesh)
154                 self.writeMeshTextureCoords(ch_obj, mesh)
155                 self.writeSkinWeights(arm,mesh)
156                 self.file.write(" }\n")
157                 self.file.write("}\n")
158                 
159                                 
160         #***********************************************
161         #Export Root Bone
162         #***********************************************
163         def writeRootBone(self,am_ob,child_obj):
164                 global mat_flip,space,root_bon,mat_ob
165                 arms = am_ob.getData()
166                 self.writeArmFrames(mat_flip, "RootFrame")
167                 for bon in arms.bones.values():
168                         if bon.hasParent():
169                                 pass
170                         else:
171                                 root_bon = bon
172                 space += 1
173                 mat_rb = self.writeCombineMatrix(root_bon)
174                 mat_r = mat_rb #* am_ob.matrixLocal
175                 name_r = root_bon.name
176                 name_f = name_r.replace(".","")
177                 self.writeArmFrames(mat_r, name_f)
178                 bon_c = self.findChildrens(root_bon)
179                 self.writeChildren(bon_c)
180                 self.file.write("  }\n")
181                 self.exportMeshArm(arms,am_ob,child_obj)
182                 
183         #***********************************************
184         #Create Children structure
185         #***********************************************
186         def writeBon(self,bon):
187                 global space
188                 mat_r = self.writeCombineMatrix(bon)
189                 name_r = bon.name
190                 name_f = name_r.replace(".","")
191                 self.writeArmFrames(mat_r, name_f)
192                 
193                 
194         def findChildrens(self,bon):
195                 bon_c = bon.children
196                 return bon_c
197                 
198         
199         def writeChildren(self,bon_c):
200                 global space,bone_list
201                 space += 1
202                 if bon_c:
203                         for bo in bon_c:
204                                 if bo.name not in bone_list:
205                                         self.writeBon(bo)
206                                         bone_list.append(bo.name)
207                                         bo_c = bo.children 
208                                         self.writeChildren(bo_c)
209                                         self.closeBrackets()
210                                 
211                                 
212                                         
213         def closeBrackets(self):
214                 global space
215                 space = space-1
216                 tab = "  "
217                 self.file.write("%s" % (tab * space))
218                 self.file.write("}\n")
219                 
220                 
221                         
222         #***********************************************
223         #Offset Matrix
224         #***********************************************
225         def writeMatrixOffset(self,bon):
226                 global  chld_obj
227                 Blender.Set('curframe', 1)
228                 pose = chld_obj.getPose()
229                 pos_b = pose.bones[bon.name]
230                 mat_b = pos_b.poseMatrix
231                 mat_b.invert()
232                 return mat_b
233
234         
235         #***********************************************
236         #Combine Matrix
237         #***********************************************
238         def writeCombineMatrix(self,bon):
239                 global  chld_obj
240                 Blender.Set('curframe', 1)
241                 pose = chld_obj.getPose()
242                 pos_b = pose.bones[bon.name]
243                 mat_b = pos_b.poseMatrix
244                 if bon.hasParent():
245                         pare = bon.parent
246                         pos_p = pose.bones[pare.name]
247                         mat_p = pos_p.poseMatrix
248                         
249                 else:
250                         mat_p = Matrix([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1])
251                 mat_p.invert()
252                 mat_f = mat_b * mat_p
253                 
254                 return mat_f
255         #***********************************************
256         #Combine Matrix
257         #***********************************************
258         def writeAnimCombineMatrix(self,bon,fre):
259                 global  chld_obj
260                 Blender.Set('curframe', fre)
261                 pose = chld_obj.getPose()
262                 pos_b = pose.bones[bon.name]
263                 mat_b = pos_b.poseMatrix
264                 if bon.hasParent():
265                         pare = bon.parent
266                         pos_p = pose.bones[pare.name]
267                         mat_p = pos_p.poseMatrix
268                         
269                 else:
270                         mat_p = Matrix([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1])
271                 mat_p.invert()
272                 mat_f = mat_b * mat_p
273                 
274                 return mat_f
275
276
277 #*********************************************************************************************************************************************
278         #***********************************************
279         #Write SkinWeights
280         #***********************************************
281         def writeSkinWeights(self, arm, mesh):
282                 global index_list
283                 v_dict = {}
284                 Blender.Set('curframe',1)
285                 self.file.write("  XSkinMeshHeader {\n")
286                 max_infl = 0
287                 #this part supply the missing getVertexInfluences(index)
288                 for v in index_list:
289                                 v_dict[v] = []
290                 for bo in arm.bones.values() :
291                         name = bo.name
292                         
293                         try :
294                                 vertx_list = mesh.getVertsFromGroup(name,1)
295                                 for vn in vertx_list:
296                                         v_dict[vn[0]].append(name)
297                                 #---------------------------------------------------
298                                 for inde in vertx_list :
299                                         vert_infl = v_dict[inde[0]]
300                                         ln_infl = len(vert_infl)
301                                         if ln_infl > max_infl :
302                                                 max_infl = ln_infl
303                                 
304                         except:
305                                 pass
306                 
307                 self.file.write("    %d; \n" % (max_infl))
308                 self.file.write("    %d; \n" % (max_infl * 3))
309                 self.file.write("    %d; \n" % (len(arm.bones.values())))
310                 self.file.write("  }\n")
311                 
312                 for bo in arm.bones.values() :
313                         bo_list = []
314                         weight_list = []
315                         name = bo.name 
316                         f_name = name.replace(".","")
317                         try :
318                                 vert_list = mesh.getVertsFromGroup(name,1)
319                                 le = 0
320                                 for indx in vert_list:
321                                         ver_infl = v_dict[indx[0]]
322                                         len_infl = float(len(ver_infl))
323                                         infl = 1 / len_infl
324                                         i = -1
325                                         for el in index_list :
326                                                 i += 1
327                                                 if el == indx[0] :
328                                                         le +=1
329                                                         bo_list.append(i)
330                                                         weight_list.append(infl)
331
332
333                                 self.file.write("  SkinWeights {\n")
334                                 self.file.write('    "%s"; \n' % (f_name))
335                                 self.file.write('     %d; \n' % (le))
336                                 count = 0
337                                 for ind in bo_list :
338                                         count += 1
339                                         if count == len(bo_list):
340                                                 self.file.write("    %d; \n" % (ind))
341                                         else :
342                                                 self.file.write("    %d, \n" % (ind))
343                                 cou = 0
344                                 for wegh in weight_list :
345                                         cou += 1
346                                         
347                                         if cou == len(weight_list):
348                                                 self.file.write("    %f; \n" % (round(wegh,6)))
349                                         else :
350                                                 self.file.write("    %f, \n" % (round(wegh,6)))
351
352                         
353                                 matx = self.writeMatrixOffset(bo)
354                                 self.writeOffsFrames(matx, name)
355                         except :
356                                 pass
357                 self.file.write("  }\n")
358                 
359
360         #***********************************************
361         # Write Matrices
362         #***********************************************
363         def writeArmFrames(self, matx, name):
364                 global space
365                 tab = "  "
366                 self.file.write("%s" % (tab * space))
367                 self.file.write("Frame ")  
368                 self.file.write("%s {\n\n" % (name))
369                 self.file.write("%s" % (tab * space))
370                 self.file.write("  FrameTransformMatrix {\n")
371                 self.file.write("%s" % (tab * space))
372                 self.file.write("    %f,%f,%f,%f,\n" %
373                                                         (round(matx[0][0],4),round(matx[0][1],4),round(matx[0][2],4),round(matx[0][3],4)))
374                 self.file.write("%s" % (tab * space))
375                 self.file.write("    %f,%f,%f,%f,\n" %
376                                                         (round(matx[1][0],4),round(matx[1][1],4),round(matx[1][2],4),round(matx[1][3],4)))
377                 self.file.write("%s" % (tab * space))   
378                 self.file.write("    %f,%f,%f,%f,\n" %
379                                                         (round(matx[2][0],4),round(matx[2][1],4),round(matx[2][2],4),round(matx[2][3],4)))
380                 self.file.write("%s" % (tab * space))
381                 self.file.write("    %f,%f,%f,%f;;\n" %
382                                                         (round(matx[3][0],4),round(matx[3][1],4),round(matx[3][2],4),round(matx[3][3],6)))
383                 self.file.write("%s" % (tab * space))
384                 self.file.write("  }\n")
385         
386         #***********************************************
387         # Write Matrices
388         #***********************************************
389         def writeOffsFrames(self, matx, name):
390                 space = 1
391                 tab = "  "
392                 self.file.write("%s" % (tab * space))
393                 self.file.write("    %f,%f,%f,%f,\n" %
394                                                         (round(matx[0][0],4),round(matx[0][1],4),round(matx[0][2],4),round(matx[0][3],4)))
395                 self.file.write("%s" % (tab * space))
396                 self.file.write("    %f,%f,%f,%f,\n" %
397                                                         (round(matx[1][0],4),round(matx[1][1],4),round(matx[1][2],4),round(matx[1][3],4)))
398                 self.file.write("%s" % (tab * space))   
399                 self.file.write("    %f,%f,%f,%f,\n" %
400                                                         (round(matx[2][0],4),round(matx[2][1],4),round(matx[2][2],4),round(matx[2][3],4)))
401                 self.file.write("%s" % (tab * space))
402                 self.file.write("    %f,%f,%f,%f;;\n" %
403                                                         (round(matx[3][0],4),round(matx[3][1],4),round(matx[3][2],4),round(matx[3][3],6)))
404                 self.file.write("%s" % (tab * space))
405                 self.file.write("  }\n")
406         
407          
408 #*********************************************************************************************************************************************
409         
410         #***********************************************
411         #HEADER
412         #***********************************************  
413         def writeHeader(self):
414                 self.file.write("xof 0303txt 0032\n\n\n")
415                 self.file.write("template VertexDuplicationIndices { \n\
416  <b8d65549-d7c9-4995-89cf-53a9a8b031e3>\n\
417  DWORD nIndices;\n\
418  DWORD nOriginalVertices;\n\
419  array DWORD indices[nIndices];\n\
420 }\n\
421 template XSkinMeshHeader {\n\
422  <3cf169ce-ff7c-44ab-93c0-f78f62d172e2>\n\
423  WORD nMaxSkinWeightsPerVertex;\n\
424  WORD nMaxSkinWeightsPerFace;\n\
425  WORD nBones;\n\
426 }\n\
427 template SkinWeights {\n\
428  <6f0d123b-bad2-4167-a0d0-80224f25fabb>\n\
429  STRING transformNodeName;\n\
430  DWORD nWeights;\n\
431  array DWORD vertexIndices[nWeights];\n\
432  array float weights[nWeights];\n\
433  Matrix4x4 matrixOffset;\n\
434 }\n\n")
435                 
436         #***********************************************
437         #CLOSE FILE
438         #***********************************************
439         def writeEnd(self):
440                 self.file.close()
441                 print "... finished"
442
443
444         #***********************************************
445         #EXPORT TEXTURES
446         #***********************************************
447         def writeTextures(self,name, tex):
448                 mesh = name.data
449                 for face in mesh.faces:
450                         if face.image and face.image.name not in tex:
451                                 tex.append(face.image.name)
452                                 
453
454
455         #***********************************************
456         #EXPORT MESH DATA with Armature
457         #***********************************************
458         def writeMeshcoordArm(self, name, meshEX,arm_ob):
459                 global index_list
460                 #ROTATION
461                 mat_arm = arm_ob.matrixWorld
462                 mat_ob = name.getMatrix('localspace')
463                 mat_ob.invert()
464                 mat = mat_arm * mat_ob
465                 mat.invert()
466                 name_f = name.name.replace(".","")
467                 self.writeArmFrames(mat, name_f)
468                 mesh = NMesh.GetRawFromObject(name.name)
469                 self.file.write("Mesh {\n")    
470                 numface=len(mesh.faces)
471                 #VERTICES NUMBER
472                 numvert = 0
473                 for face in mesh.faces:
474                         numvert = numvert + len(face.v)
475                 self.file.write("%s;\n" % (numvert))
476                 #VERTICES COORDINATES
477                 counter = 0
478                 for face in mesh.faces:
479                         counter += 1
480                         for n in range(len(face.v)):
481                                 index_list.append(face.v[n].index)
482                                 vec_vert = Vector([face.v[n].co[0], face.v[n].co[1], face.v[n].co[2], 1])
483                                 f_vec_vert = vec_vert * mat
484                                 self.file.write("%f; %f; %f;" % (round(f_vec_vert[0],4), round(f_vec_vert[1],4), round(f_vec_vert[2],4)))
485                                 if counter == numface :
486                                         if n == len(face.v)-1 :
487                                                 self.file.write(";\n")
488                                         else :
489                                                 self.file.write(",\n")
490                                 else :
491                                         self.file.write(",\n")
492
493                 #FACES NUMBER 
494                 self.file.write("%s;\n" % (numface))  
495                 coun,counter = 0, 0
496                 for face in mesh.faces :
497                         coun += 1
498                         if coun == numface:
499                                 if len(face.v) == 3:
500                                         self.file.write("3; %s, %s, %s;;\n" % (counter, counter + 2, counter + 1))
501                                         counter += 3
502                                 elif len(face.v) == 4:
503                                         self.file.write("4; %s, %s, %s, %s;;\n" % (counter, counter + 3, counter + 2, counter + 1))
504                                         counter += 4
505                                 elif len(face.v) < 3:
506                                         print "WARNING:the mesh has faces with less then 3 vertices"
507                                         print "        It my be not exported correctly."
508                         else:
509                                 
510                                 if len(face.v) == 3:
511                                         self.file.write("3; %s, %s, %s;,\n" % (counter, counter + 2, counter + 1))
512                                         counter += 3
513                                 elif len(face.v) == 4:
514                                         self.file.write("4; %s, %s, %s, %s;,\n" % (counter, counter + 3, counter + 2, counter + 1))
515                                         counter += 4
516                                 elif len(face.v) < 3:
517                                         print "WARNING:the mesh has faces with less then 3 vertices"
518                                         print "        It my be not exported correctly."
519
520         #***********************************************
521         #EXPORT MESH DATA without Armature
522         #***********************************************
523         def writeMeshcoord(self, name, mesh):
524                 global index_list
525                 #ROTATION
526                 mat_ob = mat_flip * name.matrixWorld
527                 name_f = name.name.replace(".","")
528                 self.writeArmFrames(mat_ob, name_f)
529
530                 self.file.write("Mesh {\n")    
531                 numface=len(mesh.faces)
532                 #VERTICES NUMBER
533                 numvert = 0
534                 for face in mesh.faces:
535                         numvert = numvert + len(face.v)
536                 self.file.write("%s;\n" % (numvert))
537                 #VERTICES COORDINATES
538                 counter = 0
539                 for face in mesh.faces:
540                         counter += 1
541                         for n in range(len(face.v)):
542                                 index_list.append(face.v[n].index)
543                                 self.file.write("%s; %s; %s;" % (face.v[n].co[0], face.v[n].co[1], face.v[n].co[2]))
544                                 if counter == numface :
545                                         if n == len(face.v)-1 :
546                                                 self.file.write(";\n")
547                                         else :
548                                                 self.file.write(",\n")
549                                 else :
550                                         self.file.write(",\n")
551
552                 #FACES NUMBER 
553                 self.file.write("%s;\n" % (numface))  
554                 coun,counter = 0, 0
555                 for face in mesh.faces :
556                         coun += 1
557                         if coun == numface:
558                                 if len(face.v) == 3:
559                                         self.file.write("3; %s, %s, %s;;\n" % (counter, counter + 2, counter + 1))
560                                         counter += 3
561                                 elif len(face.v) == 4:
562                                         self.file.write("4; %s, %s, %s, %s;;\n" % (counter, counter + 3, counter + 2, counter + 1))
563                                         counter += 4
564                                 elif len(face.v) < 3:
565                                         print "WARNING:the mesh has faces with less then 3 vertices(edges and points)"
566                                         print "        It my be not exported correctly."
567                         else:
568                                 
569                                 if len(face.v) == 3:
570                                         self.file.write("3; %s, %s, %s;,\n" % (counter, counter + 2, counter + 1))
571                                         counter += 3
572                                 elif len(face.v) == 4:
573                                         self.file.write("4; %s, %s, %s, %s;,\n" % (counter, counter + 3, counter + 2, counter + 1))
574                                         counter += 4
575                                 elif len(face.v) < 3:
576                                         print "WARNING:the mesh has faces with less then 3 vertices(edges and points)\n"
577                                         print "        It my be not exported correctly."
578         
579                 
580         #***********************************************
581         #MESH MATERIAL LIST
582         #***********************************************
583         def writeMeshMaterialList(self, name, obj, tex):
584                 self.file.write("  MeshMaterialList {\n")
585                 #HOW MANY MATERIALS ARE USED
586                 count = 0
587                 for mat in Material.Get():
588                         count+=1
589                 self.file.write("    %s;\n" % (len(tex) + count))
590                 #HOW MANY FACES IT HAS
591                 numfaces=len(obj.faces)
592                 self.file.write("    %s;\n" % (numfaces))
593                 ##MATERIALS INDEX FOR EVERY FACE
594                 counter = 0
595                 for face in obj.faces :
596                         counter += 1
597                         mater = face.materialIndex
598                         if counter == numfaces:
599                                 if face.image and face.image.name in tex :
600                                         self.file.write("    %s;;\n" % (tex.index(face.image.name) + count))
601                                 else :
602                                         self.file.write("    %s;;\n" % (mater))
603                         else :
604                                 if face.image and face.image.name in tex :
605                                         self.file.write("    %s,\n" % (tex.index(face.image.name) + count))
606                                 else :
607                                         self.file.write("    %s,\n" % (mater))
608                         
609                 ##MATERIAL NAME
610                 for mat in Material.Get():
611                         self.file.write("  Material")
612                         name_m = mat.name
613                         name_f = name_m.replace(".","")
614                         self.file.write(" %s "% (name_f))
615                         self.file.write("{\n")
616                         self.file.write("    %s; %s; %s;" % (mat.R, mat.G, mat.B))
617                         self.file.write("%s;;\n" % (mat.alpha))
618                         self.file.write("    %s;\n" % (mat.spec))
619                         self.file.write("    %s; %s; %s;;\n" % (mat.specR, mat.specG, mat.specB))
620                         self.file.write("    0.0; 0.0; 0.0;;\n")
621                         self.file.write("  }\n") 
622                 
623                 for mat in tex:
624                         self.file.write("  Material Mat")
625                         self.file.write("%s "% (len(tex)))
626                         self.file.write("{\n")
627                         self.file.write("    1.0; 1.0; 1.0; 1.0;;\n")
628                         self.file.write("    1.0;\n")
629                         self.file.write("    1.0; 1.0; 1.0;;\n")
630                         self.file.write("    0.0; 0.0; 0.0;;\n")
631                         self.file.write("  TextureFilename {")
632                         self.file.write('    "%s" ;'% (mat))
633                         self.file.write("  }\n")
634                         self.file.write("  }\n") 
635                 self.file.write("    }\n")
636
637         #***********************************************
638         #MESH NORMALS
639         #***********************************************
640         def writeMeshNormals(self,name,mesh):
641                 self.file.write("  MeshNormals {\n")
642                 #VERTICES NUMBER
643                 numvert = 0
644                 for face in mesh.faces:
645                         numvert = numvert + len(face.v)
646                 self.file.write("%s;\n" % (numvert))
647                 numfaces=len(mesh.faces)
648                 
649                 #VERTICES NORMAL
650                 counter = 0
651                 for face in mesh.faces:
652                         counter += 1  
653                         for n in range(len(face.v)):
654                                 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))))
655                                 if counter == numfaces :
656                                         if n == len(face.v)-1 :
657                                                 self.file.write(";\n")
658                                         else :
659                                                 self.file.write(",\n")
660                                 else :
661                                         self.file.write(",\n")
662                 
663
664
665                 #FACES NUMBER 
666                 self.file.write("%s;\n" % (numfaces))  
667                 coun,counter = 0, 0
668                 for face in mesh.faces :
669                         coun += 1
670                         if coun == numfaces:
671                                 if len(face.v) == 3:
672                                         self.file.write("3; %s, %s, %s;;\n" % (counter, counter + 2, counter + 1))
673                                         counter += 3
674                                 else :
675                                         self.file.write("4; %s, %s, %s, %s;;\n" % (counter, counter + 3, counter + 2, counter + 1))
676                                         counter += 4
677                         else:
678                                 
679                                 if len(face.v) == 3:
680                                         self.file.write("3; %s, %s, %s;,\n" % (counter, counter + 2, counter + 1))
681                                         counter += 3
682                                 else :
683                                         self.file.write("4; %s, %s, %s, %s;,\n" % (counter, counter + 3, counter + 2, counter + 1))
684                                         counter += 4
685                 self.file.write("}\n")
686
687         #***********************************************
688         #MESH TEXTURE COORDS
689         #***********************************************
690         def writeMeshTextureCoords(self, name, mesh):
691                 if mesh.hasFaceUV():
692                         self.file.write("MeshTextureCoords {\n")
693                         #VERTICES NUMBER
694                         numvert = 0
695                         for face in mesh.faces:
696                                 numvert += len(face.v)
697                         self.file.write("%s;\n" % (numvert))
698                         #UV COORDS
699                         numfaces = len(mesh.faces)
700                         counter = -1
701                         co = 0
702                         for face in mesh.faces:
703                                 counter += 1
704                                 co += 1
705                                 for n in range(len(face.v)):
706                                         self.file.write("%s;%s;" % (mesh.faces[counter].uv[n][0], -mesh.faces[counter].uv[n][1]))
707                                         if co == numfaces :
708                                                 if n == len(face.v) - 1 :
709                                                         self.file.write(";\n")
710                                                 else :
711                                                         self.file.write(",\n")
712                                         else :
713                                                 self.file.write(",\n")
714
715                         self.file.write("}\n")
716 #***********************************************#***********************************************#***********************************************
717         #***********************************************
718         #FRAMES
719         #***********************************************
720         def writeFrames(self, matx):
721                 
722                 self.file.write("%s,%s,%s,%s," %
723                                                         (round(matx[0][0],4),round(matx[0][1],4),round(matx[0][2],4),round(matx[0][3],6)))
724                 self.file.write("%s,%s,%s,%s," %
725                                                         (round(matx[1][0],4),round(matx[1][1],4),round(matx[1][2],4),round(matx[1][3],6)))      
726                 self.file.write("%s,%s,%s,%s," %
727                                                         (round(matx[2][0],4),round(matx[2][1],4),round(matx[2][2],4),round(matx[2][3],6)))
728                 self.file.write("%s,%s,%s,%s;;" %
729                                                         (round(matx[3][0],4),round(matx[3][1],4),round(matx[3][2],4),round(matx[3][3],6)))
730                 
731                 
732                 
733         
734         
735         #***********************************************
736         #WRITE ANIMATION KEYS
737         #***********************************************
738         def writeAnimation(self,arm_ob):
739                 global mat_dict
740                 arm = arm_ob.getData()
741                 act_list = arm_ob.getAction()
742                 ip = act_list.getAllChannelIpos()
743                 for bon in arm.bones.values() :
744                         point_list = []
745                         name = bon.name
746                         name_f = name.replace(".", "")
747                         try :
748                                 ip_bon_channel = ip[bon.name]
749                                 ip_bon_name = ip_bon_channel.getName()
750                                 
751                                 ip_bon = Blender.Ipo.Get(ip_bon_name)
752                                 poi = ip_bon.getCurves()
753                                 
754                                 for po in poi[3].getPoints():
755                                         a = po.getPoints()
756                                         point_list.append(int(a[0]))
757                                 #point_list.pop(0) 
758                                 
759                                 self.file.write(" Animation { \n")
760                                 self.file.write("  {%s}\n" %(name_f))
761                                 self.file.write("  AnimationKey { \n")
762                                 self.file.write("   4;\n")
763                                 self.file.write("   %s; \n" % (len(point_list)))
764
765                                 for fr in point_list:
766                                         mat = self.writeAnimCombineMatrix(bon,fr)       
767                                         
768                                         self.file.write("   %s;" % (fr))
769                                         self.file.write("16;")
770                                 
771                                         self.writeFrames(mat)
772                                 
773                                         if fr == point_list[len(point_list)-1]:
774                                                 self.file.write(";\n")
775                                         else:
776                                                 self.file.write(",\n")
777                                 self.file.write("   }\n")
778                                 self.file.write(" }\n")
779                                 self.file.write("\n")
780                         except:
781                                 pass
782                 
783                 
784
785         #***********************************************
786         #WRITE ANIMATION KEYS
787         #***********************************************
788         def writeAnimationObj(self, obj):
789                 point_list = []
790                 ip = obj.getIpo()
791                 poi = ip.getCurves()
792                 for po in poi[0].getPoints():
793                         a = po.getPoints()
794                         point_list.append(int(a[0]))
795                 point_list.pop(0)
796                 
797                 self.file.write(" Animation {\n")
798                 self.file.write("  {")
799                 self.file.write("%s }\n" % (obj.name))
800                 self.file.write("   AnimationKey { \n")
801                 self.file.write("   4;\n")
802                 self.file.write("   %s; \n" % (len(point_list)+1))
803                 self.file.write("   %s;" % (1))
804                 self.file.write("16;")
805                 Blender.Set('curframe',1)
806                 mat = obj.matrixWorld * mat_flip
807                 self.writeFrames(mat)
808                 self.file.write(",\n")
809                 for fr in point_list:
810                         self.file.write("   %s;" % (fr))
811                         self.file.write("16;")
812                         Blender.Set('curframe',fr)
813                                 
814                         mat_new = obj.matrixWorld * mat_flip
815                         self.writeFrames(mat_new)
816
817                         if fr == point_list[len(point_list)-1]:
818                                 self.file.write(";\n")
819                         else:
820                                 self.file.write(",\n")
821                 self.file.write("   }\n")
822                 self.file.write("  }\n")
823
824         #***********************************************
825         #WRITE ANIMATION KEYS
826         #***********************************************
827         def writeAnimationObjArm(self, obj):
828                 point_list = []
829                 ip = obj.getIpo()
830                 poi = ip.getCurves()
831                 for po in poi[0].getPoints():
832                         a = po.getPoints()
833                         point_list.append(int(a[0]))
834                 point_list.pop(0)
835                 
836                 self.file.write(" Animation {\n")
837                 self.file.write("  {RootFrame}\n" )
838                 self.file.write("   AnimationKey { \n")
839                 self.file.write("   4;\n")
840                 self.file.write("   %s; \n" % (len(point_list)+1))
841                 self.file.write("   %s;" % (1))
842                 self.file.write("16;")
843                 Blender.Set('curframe',1)
844                 mat = mat_flip * obj.getMatrix('worldspace')
845                 self.writeFrames(mat)
846                 self.file.write(",\n")
847                 for fr in point_list:
848                         self.file.write("   %s;" % (fr))
849                         self.file.write("16;")
850                         Blender.Set('curframe',fr)
851                                 
852                         mat_new = mat_flip * obj.getMatrix('worldspace')
853                         self.writeFrames(mat_new)
854
855                         if fr == point_list[len(point_list)-1]:
856                                 self.file.write(";\n")
857                         else:
858                                 self.file.write(",\n")
859                 self.file.write("   }\n")
860                 self.file.write("  }\n")
861                 
862 #***********************************************#***********************************************#***********************************************
863
864
865
866 #***********************************************
867 # MAIN
868 #***********************************************
869
870 def my_callback(filename):
871         if filename.find('.x', -2) <= 0: filename += '.x' 
872         xexport = xExport(filename)
873         xexport.SelectObjs()
874
875 def my_callback_sel(filename):
876         if filename.find('.x', -2) <= 0: filename += '.x' 
877         xexport = xExport(filename)
878         xexport.exportSelMesh()
879
880 arg = __script__['arg']
881
882 if arg == 'exportsel':
883         fname = Blender.sys.makename(ext = ".x")
884         Blender.Window.FileSelector(my_callback_sel, "Export DirectX", fname)   
885 else:
886         fname = Blender.sys.makename(ext = ".x")
887         Blender.Window.FileSelector(my_callback, "Export DirectX", fname)       
888