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

  1. #!BPY
  2.  
  3. """ Registration info for Blender menus:
  4. Name: 'DirectX (.x)...'
  5. Blender: 234
  6. Group: 'Export'
  7. Submenu: 'Only mesh data...' mesh
  8. Submenu: 'Animation(not armature yet)...' anim
  9. Tip: 'Export to DirectX 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 Blender uv-textured meshes with animation frame keys to
  18. DirectX 7's text file format.
  19.  
  20. Usage:
  21.  
  22. Run the script and check console for possible warning messages.
  23.  
  24. Supported:<br>
  25.     UV-textured meshes with animation frame (location, rotation) keys.
  26.  
  27. Known issues:<br>
  28.     Some DX format viewers don't support Material names with dots
  29. ('.') in them.
  30.  
  31. Notes:<br>
  32.     Check author's site or the elYsiun forum for a new beta version of the
  33. DX exporter.
  34. """
  35.  
  36.  
  37. # $Id: DirectXExporter.py,v 1.6 2004/11/07 16:31:13 ianwill Exp $
  38. #
  39. # DirectX.py version 1.0
  40. # Copyright (C) 2003  Arben OMARI -- omariarben@everyday.com  
  41. #
  42. # This program is free software; you can redistribute it and/or modify
  43. # it under the terms of the GNU General Public License as published by
  44. # the Free Software Foundation; either version 2 of the License, or
  45. # (at your option) any later version.
  46. #
  47. # This program is distributed in the hope that it will be useful,
  48. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  49. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  50. # GNU General Public License for more details.
  51.  
  52. # This script export meshes created with Blender in DirectX file format
  53. # it exports meshes,materials,normals,texturecoords and and animations
  54.  
  55. # Grab the latest version here :www.omariben.too.it
  56.  
  57. import Blender
  58. from Blender import Types, Object, NMesh, Material
  59. #import string
  60. from math import *
  61.  
  62.  
  63.  
  64.     
  65. #***********************************************
  66. #***********************************************
  67. #                EXPORTER
  68. #***********************************************
  69. #***********************************************
  70.  
  71. class xExport:
  72.     def __init__(self, filename):
  73.         self.file = open(filename, "w")
  74.  
  75.     #***********************************************
  76.     #  Export animations
  77.     #***********************************************
  78.     def exportAnim(self):
  79.         tex = []
  80.         print "exporting ..."
  81.         self.writeHeader()
  82.         for name in Object.Get():
  83.             obj = name.getData()
  84.             if type(obj) == Types.NMeshType :
  85.                     
  86.                 self.writeFrames(name, obj)    
  87.                 self.writeMeshcoord(name, obj )
  88.                 self.writeMeshMaterialList(name, obj, tex)
  89.                 self.writeMeshNormals(name, obj)
  90.                 self.writeMeshTextureCoords(name, obj)
  91.                 self.file.write("}\n")
  92.                 self.file.write("}\n")
  93.                 self.writeAnimation(name, obj)
  94.             
  95.         self.writeEnd()
  96.  
  97.     #***********************************************
  98.     #  Export geometry
  99.     #***********************************************
  100.     def exportTex(self):
  101.         tex = []
  102.         print "exporting ..."
  103.         self.writeHeader()
  104.         for name in Object.Get():
  105.             obj = name.getData()
  106.             if type(obj) == Types.NMeshType :        
  107.                 self.writeMeshcoord(name, obj )
  108.                 self.writeMeshMaterialList(name, obj, tex)
  109.                 self.writeMeshNormals(name, obj)
  110.                 self.writeMeshTextureCoords(name, obj)
  111.                 self.file.write("}\n")
  112.  
  113.         self.writeEnd()
  114.     
  115.     #***********************************************
  116.     #HEADER
  117.     #***********************************************  
  118.     def writeHeader(self):
  119.         self.file.write("xof 0302txt 0064\n")
  120.         self.file.write("\n")
  121.         self.file.write("Header{\n")
  122.         self.file.write("1;0;1;\n")
  123.         self.file.write("}\n")
  124.  
  125.     #***********************************************
  126.     #CLOSE FILE
  127.     #***********************************************
  128.     def writeEnd(self):
  129.         self.file.close()
  130.         print "... finished"
  131.     
  132.         
  133.  
  134.     #***********************************************
  135.     #EXPORT TEXTURES
  136.     #***********************************************
  137.     def writeTextures(self,name, tex):
  138.         mesh = name.data
  139.         for face in mesh.faces:
  140.             if face.image and face.image.name not in tex:
  141.                 tex.append(face.image.name)
  142.                 
  143.  
  144.     #***********************************************
  145.     #EXPORT MESH DATA
  146.     #***********************************************
  147.     def writeMeshcoord(self, name, obj ):
  148.         
  149.         self.file.write("Mesh Mesh_%s {\n" % (name.name))    
  150.         numfaces=len(obj.faces)
  151.         #POSITION
  152.         loc = name.getMatrix()
  153.         x = loc[3][0]
  154.         y = loc[3][1]
  155.         z = loc[3][2]
  156.         #VERTICES NUMBER
  157.         mesh = name.data
  158.         numvert = 0
  159.         for face in mesh.faces:
  160.             numvert = numvert + len(face.v)
  161.         self.file.write("%s;\n" % (numvert))
  162.         #VERTICES COORDINATES
  163.         counter = 0
  164.         for face in mesh.faces:
  165.             counter += 1
  166.             if counter == numfaces:
  167.                 if len(face.v) == 4:
  168.                     self.file.write("%s; %s; %s;,\n" % ((face.v[0].co[0] + x), face.v[0].co[1] + y, face.v[0].co[2] + z))
  169.                     self.file.write("%s; %s; %s;,\n" % ((face.v[1].co[0] + x), face.v[1].co[1] + y, face.v[1].co[2] + z))        
  170.                     self.file.write("%s; %s; %s;,\n" % ((face.v[2].co[0] + x), face.v[2].co[1] + y, face.v[2].co[2] + z))
  171.                     self.file.write("%s; %s; %s;;\n" % ((face.v[3].co[0] + x), face.v[3].co[1] + y, face.v[3].co[2] + z))
  172.                 elif len(face.v) == 3 :
  173.                     self.file.write("%s; %s; %s;,\n" % ((face.v[0].co[0] + x), face.v[0].co[1] + y, face.v[0].co[2] + z))
  174.                     self.file.write("%s; %s; %s;,\n" % ((face.v[1].co[0] + x), face.v[1].co[1] + y, face.v[1].co[2] + z))        
  175.                     self.file.write("%s; %s; %s;;\n" % ((face.v[2].co[0] + x), face.v[2].co[1] + y, face.v[2].co[2] + z))
  176.                     
  177.             else :
  178.                 if len(face.v) == 4:
  179.                     self.file.write("%s; %s; %s;,\n" % ((face.v[0].co[0] + x), face.v[0].co[1] + y, face.v[0].co[2] + z))
  180.                     self.file.write("%s; %s; %s;,\n" % ((face.v[1].co[0] + x), face.v[1].co[1] + y, face.v[1].co[2] + z))        
  181.                     self.file.write("%s; %s; %s;,\n" % ((face.v[2].co[0] + x), face.v[2].co[1] + y, face.v[2].co[2] + z))
  182.                     self.file.write("%s; %s; %s;,\n" % ((face.v[3].co[0] + x), face.v[3].co[1] + y, face.v[3].co[2] + z))
  183.                 elif len(face.v) == 3:
  184.                     self.file.write("%s; %s; %s;,\n" % ((face.v[0].co[0] + x), face.v[0].co[1] + y, face.v[0].co[2] + z))
  185.                     self.file.write("%s; %s; %s;,\n" % ((face.v[1].co[0] + x), face.v[1].co[1] + y, face.v[1].co[2] + z))        
  186.                     self.file.write("%s; %s; %s;,\n" % ((face.v[2].co[0] + x), face.v[2].co[1] + y, face.v[2].co[2] + z))
  187.                     
  188.  
  189.  
  190.         #FACES NUMBER 
  191.         
  192.         self.file.write("%s;\n" % (numfaces))  
  193.         #FACES INDEX
  194.         numface=len(obj.faces)
  195.         coun,counter = 0, 0
  196.         for face in mesh.faces :
  197.             coun += 1
  198.             if coun == numface:
  199.                 if len(face.v) == 3:
  200.                     self.file.write("3; %s; %s; %s;;\n" % (counter, counter + 1, counter + 2))
  201.                     counter += 3
  202.                 elif len(face.v) == 4:
  203.                     self.file.write("4; %s; %s; %s; %s;;\n" % (counter, counter + 1, counter + 2, counter + 3))
  204.                     counter += 4
  205.                 elif len(face.v) == 2:
  206.                     print "WARNING:the mesh has faces with less then 3 vertices"
  207.             else:
  208.                 
  209.                 if len(face.v) == 3:
  210.                     self.file.write("3; %s; %s; %s;,\n" % (counter, counter + 1, counter + 2))
  211.                     counter += 3
  212.                 elif len(face.v) == 4:
  213.                     self.file.write("4; %s; %s; %s; %s;,\n" % (counter, counter + 1, counter + 2, counter + 3))
  214.                     counter += 4
  215.                 elif len(face.v) == 2:
  216.                     print "WARNING:the mesh has faces with less then 3 vertices"
  217.                 
  218.         
  219.         
  220.         
  221.         
  222.     #***********************************************
  223.     #MESH MATERIAL LIST
  224.     #***********************************************
  225.     def writeMeshMaterialList(self, name, obj, tex):
  226.         self.file.write("  MeshMaterialList {\n")
  227.         #HOW MANY MATERIALS ARE USED
  228.         count = 0
  229.         for mat in Material.Get():
  230.             count+=1
  231.         self.file.write("    %s;\n" % (len(tex) + count))
  232.         #HOW MANY FACES IT HAS
  233.         numfaces=len(obj.faces)
  234.         self.file.write("    %s;\n" % (numfaces))
  235.         ##MATERIALS INDEX FOR EVERY FACE
  236.         counter = 0
  237.         for face in obj.faces :
  238.             counter += 1
  239.             mater = face.materialIndex
  240.             if counter == numfaces:
  241.                 if face.image and face.image.name in tex :
  242.                     self.file.write("    %s;;\n" % (tex.index(face.image.name) + count))
  243.                 else :
  244.                     self.file.write("    %s;;\n" % (mater))
  245.             else :
  246.                 if face.image and face.image.name in tex :
  247.                     self.file.write("    %s,\n" % (tex.index(face.image.name) + count))
  248.                 else :
  249.                     self.file.write("    %s,\n" % (mater))
  250.             
  251.         ##MATERIAL NAME
  252.         for mat in Material.Get():
  253.             self.file.write("  Material")
  254.             for a in range(0,len(mat.name)):
  255.                 if mat.name[a] == ".":
  256.                     print "WARNING:the material " + mat.name + " contains '.' within.Many viewers may refuse to read the exported file"
  257.             self.file.write(" %s "% (mat.name))
  258.             self.file.write("{\n")
  259.             self.file.write("    %s; %s; %s;" % (mat.R, mat.G, mat.B))
  260.             self.file.write("%s;;\n" % (mat.alpha))
  261.             self.file.write("    %s;\n" % (mat.spec))
  262.             self.file.write("    %s; %s; %s;;\n" % (mat.specR, mat.specG, mat.specB))
  263.             self.file.write("    0.0; 0.0; 0.0;;\n")
  264.             self.file.write("  }\n") 
  265.         
  266.         for mat in tex:
  267.             self.file.write("  Material Mat")
  268.             self.file.write("%s "% (len(tex)))
  269.             self.file.write("{\n")
  270.             self.file.write("    1.0; 1.0; 1.0; 1.0;;\n")
  271.             self.file.write("    1.0;\n")
  272.             self.file.write("    1.0; 1.0; 1.0;;\n")
  273.             self.file.write("    0.0; 0.0; 0.0;;\n")
  274.             self.file.write("  TextureFilename {\n")
  275.             self.file.write('    "%s" ;'% (face.image.name))
  276.             self.file.write("  }\n")
  277.             self.file.write("  }\n") 
  278.         self.file.write("    }\n")
  279.     #***********************************************
  280.     #MESH NORMALS
  281.     #***********************************************
  282.     def writeMeshNormals(self,name,obj):
  283.         self.file.write(" MeshNormals {\n")
  284.         #VERTICES NUMBER
  285.         numvert=len(obj.verts)
  286.         self.file.write("%s;\n" % (numvert))
  287.         #VERTICES NORMAL
  288.         counter = 0
  289.         for vert in obj.verts:
  290.             counter += 1  
  291.             if counter == numvert:
  292.                 self.file.write("%s; %s; %s;;\n" % (vert.no[0], vert.no[1], vert.no[2]))
  293.             else :
  294.                 self.file.write("%s; %s; %s;,\n" % (vert.no[0], vert.no[1], vert.no[2]))
  295.         #FACES NUMBER 
  296.         numfaces=len(obj.faces)
  297.         self.file.write("%s;\n" % (numfaces))  
  298.         #FACES INDEX
  299.         counter = 0
  300.         for face in obj.faces :
  301.             counter += 1
  302.             if counter == numfaces:
  303.                 if len(face.v) == 3:
  304.                     self.file.write("3; %s; %s; %s;;\n" % (face[0].index, face[1].index, face[2].index))
  305.                 elif len(face.v) == 4:
  306.                     self.file.write("4; %s; %s; %s; %s;;\n" % (face[0].index, face[1].index, face[2].index, face[3].index))
  307.             else:
  308.                 if len(face.v) == 3:
  309.                     self.file.write("3; %s; %s; %s;,\n" % (face[0].index, face[1].index, face[2].index))
  310.                 elif len(face.v) == 4 :
  311.                     self.file.write("4; %s; %s; %s; %s;,\n" % (face[0].index, face[1].index, face[2].index, face[3].index))
  312.         self.file.write("}\n")
  313.     #***********************************************
  314.     #MESH TEXTURE COORDS
  315.     #***********************************************
  316.     def writeMeshTextureCoords(self, name, obj):
  317.             if obj.hasFaceUV():
  318.                 self.file.write("MeshTextureCoords {\n")
  319.                 #VERTICES NUMBER
  320.                 mesh = name.data
  321.                 numvert = 0
  322.                 for face in mesh.faces:
  323.                     numvert = numvert + len(face.v)
  324.                 self.file.write("%s;\n" % (numvert))
  325.                 #UV COORDS
  326.                 counter = -1
  327.                 for face in mesh.faces:
  328.                     counter += 1
  329.                     if len(face.v) == 4:
  330.                         self.file.write("%s;%s;,\n" % (mesh.faces[counter].uv[0][0], -mesh.faces[counter].uv[0][1]))
  331.                         self.file.write("%s;%s;,\n" % (mesh.faces[counter].uv[1][0], -mesh.faces[counter].uv[1][1]))
  332.                         self.file.write("%s;%s;,\n" % (mesh.faces[counter].uv[2][0], -mesh.faces[counter].uv[2][1]))
  333.                         self.file.write("%s;%s;,\n" % (mesh.faces[counter].uv[3][0], -mesh.faces[counter].uv[3][1]))
  334.                     elif len(face.v) == 3:
  335.                         self.file.write("%s;%s;,\n" % (mesh.faces[counter].uv[0][0], -mesh.faces[counter].uv[0][1]))
  336.                         self.file.write("%s;%s;,\n" % (mesh.faces[counter].uv[1][0], -mesh.faces[counter].uv[1][1]))
  337.                         self.file.write("%s;%s;,\n" % (mesh.faces[counter].uv[2][0], -mesh.faces[counter].uv[2][1]))
  338.  
  339.                 self.file.write("}\n")
  340.  
  341.     #***********************************************
  342.     #FRAMES
  343.     #***********************************************
  344.     def writeFrames(self, name, obj):
  345.         matx = name.getMatrix()
  346.         self.file.write("Frame Fr_")  
  347.         self.file.write("%s {\n" % (obj.name))
  348.         self.file.write(" FrameTransformMatrix {\n")
  349.         self.file.write(" %s,%s,%s,%s,\n" %
  350.                             (round(matx[0][0],6),round(matx[0][1],6),round(matx[0][2],6),round(matx[0][3],6)))
  351.         self.file.write(" %s,%s,%s,%s,\n" %
  352.                             (round(matx[1][0],6),round(matx[1][1],6),round(matx[1][2],6),round(matx[1][3],6)))
  353.         self.file.write(" %s,%s,%s,%s,\n" %
  354.                             (round(matx[2][0],6),round(matx[2][1],6),round(matx[2][2],6),round(matx[2][3],6)))
  355.         self.file.write(" %s,%s,%s,%s;;\n" %
  356.                             (round(matx[3][0],6),round(matx[3][1],6),round(matx[3][2],6),round(matx[3][3],6)))
  357.         self.file.write(" }\n")
  358.     #***********************************************
  359.     #WRITE ANIMATION KEYS
  360.     #***********************************************
  361.     def writeAnimation(self, name, obj):
  362.         startFr = Blender.Get('staframe')
  363.         endFr = Blender.Get('endframe')
  364.         self.file.write("AnimationSet animset_")
  365.         self.file.write("%s {\n" % (obj.name))
  366.         self.file.write(" Animation anim_")
  367.         self.file.write("%s { \n" % (obj.name))
  368.         self.file.write("  {Fr_")
  369.         self.file.write("%s }\n" % (obj.name))
  370.         self.file.write("   AnimationKey { \n")
  371.         self.file.write("   0;\n")
  372.         self.file.write("   %s; \n" % (endFr))
  373.         for fr in range(startFr,endFr + 1) :
  374.             self.file.write("   %s; " % (fr))
  375.             self.file.write("4; ")
  376.             Blender.Set('curframe',fr)
  377.             rot = name.rot
  378.             rot_x = rot[0]
  379.             rot_y = rot[1]
  380.             rot_z = rot[2]
  381.             quat = self.euler2quat(rot_x,rot_y,rot_z)
  382.             self.file.write("%s, %s, %s,%s;;" % 
  383.                             (quat[0],quat[1],quat[2],quat[3]))
  384.             if fr == endFr:
  385.                 self.file.write(";\n")
  386.             else:
  387.                 self.file.write(",\n")
  388.         self.file.write("   }\n")
  389.         self.file.write("   AnimationKey { \n")
  390.         self.file.write("   2;\n")
  391.         self.file.write("   %s; \n" % (endFr))
  392.         for fr in range(startFr,endFr + 1) :
  393.             self.file.write("   %s; " % (fr))
  394.             self.file.write("3; ")
  395.             Blender.Set('curframe',fr)
  396.             loc = name.loc
  397.             self.file.write("%s, %s, %s;;" %
  398.                             (loc[0],loc[1],loc[2]))
  399.             if fr == endFr:
  400.                 self.file.write(";\n")
  401.             else:
  402.                 self.file.write(",\n")
  403.         self.file.write("   }\n")
  404.         self.file.write("   AnimationKey { \n")
  405.         self.file.write("   1;\n")
  406.         self.file.write("   %s; \n" % (endFr))
  407.         for fr in range(startFr,endFr + 1) :
  408.             self.file.write("   %s; " % (fr))
  409.             self.file.write("3; ")
  410.             Blender.Set('curframe',fr)
  411.             size = name.size
  412.             self.file.write("%s, %s, %s;;" %
  413.                             (size[0],size[1],size[2]))
  414.             if fr == endFr:
  415.                 self.file.write(";\n")
  416.             else:
  417.                 self.file.write(",\n")
  418.         self.file.write("   }\n")
  419.         self.file.write("  }\n")
  420.         self.file.write(" }\n")
  421.  
  422.     def euler2quat(self,rot_x,rot_y,rot_z):
  423.         c_x = cos(rot_x / 2)
  424.         c_y = cos(rot_y / 2)
  425.         c_z = cos(rot_z / 2)
  426.  
  427.         s_x = sin(rot_x / 2)
  428.         s_y = sin(rot_y / 2)
  429.         s_z = sin(rot_z / 2)
  430.  
  431.         cy_cz = c_y * c_z
  432.         sy_sz = s_y * s_z
  433.  
  434.         quat_w = c_x * cy_cz - s_x * sy_sz
  435.         quat_x = s_x * cy_cz + c_x * sy_sz
  436.         quat_y = c_x * s_y * c_z - s_x * c_y * s_z
  437.         quat_z = c_x * c_y * s_z + s_x * s_y * c_z
  438.  
  439.         return(quat_w,quat_x,quat_y,quat_z)
  440.  
  441. #***********************************************
  442. # MAIN
  443. #***********************************************
  444.  
  445.     
  446. def my_callback(filename):
  447.     if filename.find('.x', -2) <= 0: filename += '.x' # add '.x' if the user didn't
  448.     xexport = xExport(filename)
  449.     arg = __script__['arg']
  450.     if arg == 'anim':
  451.         xexport.exportAnim()
  452.     else:
  453.         xexport.exportTex()
  454.  
  455. fname = Blender.sys.makename(ext = ".x")
  456. Blender.Window.FileSelector(my_callback, "Export DirectX",fname)
  457.