home *** CD-ROM | disk | FTP | other *** search
/ Windows News 2005 November / WNnov2005.iso / Windows / Equipement / Blender / blender-2.37a-windows.exe / $_5_ / .blender / scripts / DirectX8Exporter.py < prev    next >
Text File  |  2004-11-07  |  24KB  |  748 lines

  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: DirectX8Exporter.py,v 1.4 2004/11/07 16:31:13 ianwill Exp $
  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)    
  748.