3 """ Registration info for Blender menus:
7 Submenu: 'Only mesh data...' mesh
8 Submenu: 'Animation(not armature yet)...' anim
9 Tip: 'Export to DirectX text file format format.'
11 # DirectX.py version 1.0
12 # Copyright (C) 2003 Arben OMARI -- aromari@tin.it
14 # This program is free software; you can redistribute it and/or modify
15 # it under the terms of the GNU General Public License as published by
16 # the Free Software Foundation; either version 2 of the License, or
17 # (at your option) any later version.
19 # This program is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 # GNU General Public License for more details.
24 # This script export meshes created with Blender in DirectX file format
25 # it exports meshes,materials,normals,texturecoords and and animations
27 # Grab the latest version here :www.omariben.too.it
30 from Blender import Types, Object, NMesh, Material
37 #***********************************************
38 #***********************************************
40 #***********************************************
41 #***********************************************
44 def __init__(self, filename):
45 self.file = open(filename, "w")
47 #***********************************************
49 #***********************************************
54 for name in Object.Get():
56 if type(obj) == Types.NMeshType :
57 self.writeMaterials(name,tex)
58 self.writeFrames(name, obj)
59 self.writeMeshcoord(name, obj )
60 self.writeMeshMaterialList(name, obj, tex)
61 self.writeMeshNormals(name, obj)
62 self.writeMeshTextureCoords(name, obj)
63 self.file.write("}\n")
64 self.file.write("}\n")
65 self.writeAnimation(name, obj)
69 #***********************************************
71 #***********************************************
76 for name in Object.Get():
78 if type(obj) == Types.NMeshType :
79 self.writeMaterials(name,tex)
80 self.writeMeshcoord(name, obj )
81 self.writeMeshMaterialList(name, obj, tex)
82 self.writeMeshNormals(name, obj)
83 self.writeMeshTextureCoords(name, obj)
84 self.file.write("}\n")
88 #***********************************************
90 #***********************************************
91 def writeHeader(self):
92 self.file.write("xof 0302txt 0064\n")
94 self.file.write("Header{\n")
95 self.file.write("1;0;1;\n")
96 self.file.write("}\n")
98 #***********************************************
100 #***********************************************
104 #***********************************************
106 #***********************************************
107 def writeMaterials(self,name,tex):
108 for mat in Material.Get():
109 self.file.write("Material")
110 self.file.write(" %s "% (mat.name))
111 self.file.write("{\n")
112 self.file.write("%s; %s; %s;" % (mat.R, mat.G, mat.B))
113 self.file.write("%s;;\n" % (mat.alpha))
114 self.file.write("%s;\n" % (mat.spec))
115 self.file.write("%s; %s; %s;;\n" % (mat.specR, mat.specG, mat.specB))
116 self.file.write("0.0; 0.0; 0.0;;\n")
117 self.file.write("TextureFilename {\n")
118 self.file.write('none ;')
119 self.file.write("}\n")
120 self.file.write("}\n")
121 self.writeTextures(name, tex)
124 #***********************************************
126 #***********************************************
127 def writeTextures(self,name, tex):
129 for face in mesh.faces:
130 if face.image and face.image.name not in tex:
131 tex.append(face.image.name)
132 self.file.write("Material Mat")
133 self.file.write("%s "% (len(tex)))
134 self.file.write("{\n")
135 self.file.write("1.0; 1.0; 1.0; 1.0;;\n")
136 self.file.write("1.0;\n")
137 self.file.write("1.0; 1.0; 1.0;;\n")
138 self.file.write("0.0; 0.0; 0.0;;\n")
139 self.file.write("TextureFilename {\n")
140 self.file.write('"%s" ;'% (face.image.name))
141 self.file.write("}\n")
142 self.file.write("}\n")
145 #***********************************************
147 #***********************************************
148 def writeMeshcoord(self, name, obj ):
150 self.file.write("Mesh Mesh_%s {\n" % (name.name))
151 numfaces=len(obj.faces)
153 loc = name.getMatrix()
160 for face in mesh.faces:
161 numvert = numvert + len(face.v)
162 self.file.write("%s;\n" % (numvert))
163 #VERTICES COORDINATES
165 for face in mesh.faces:
167 if counter == numfaces:
169 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))
170 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))
171 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))
172 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))
173 elif len(face.v) == 3 :
174 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))
175 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))
176 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))
180 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))
181 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))
182 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))
183 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))
184 elif len(face.v) == 3:
185 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))
186 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))
187 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))
193 self.file.write("%s;\n" % (numfaces))
195 numface=len(obj.faces)
197 for face in mesh.faces :
201 self.file.write("3; %s; %s; %s;;\n" % (counter, counter + 1, counter + 2))
204 self.file.write("4; %s; %s; %s; %s;;\n" % (counter, counter + 1, counter + 2, counter + 3))
209 self.file.write("3; %s; %s; %s;,\n" % (counter, counter + 1, counter + 2))
212 self.file.write("4; %s; %s; %s; %s;,\n" % (counter, counter + 1, counter + 2, counter + 3))
220 #***********************************************
222 #***********************************************
223 def writeMeshMaterialList(self, name, obj, tex):
224 self.file.write("//LET'S BEGIN WITH OPTIONAL DATA\n")
225 self.file.write(" MeshMaterialList {\n")
226 #HOW MANY MATERIALS ARE USED
228 for mat in Material.Get():
230 self.file.write("%s;\n" % (len(tex) + count))
231 #HOW MANY FACES IT HAS
232 numfaces=len(obj.faces)
233 self.file.write("%s;\n" % (numfaces))
234 ##MATERIALS INDEX FOR EVERY FACE
236 for face in obj.faces :
238 mater = face.materialIndex
239 if counter == numfaces:
240 if face.image and face.image.name in tex :
241 self.file.write("%s;;\n" % (tex.index(face.image.name) + count))
243 self.file.write("%s;;\n" % (mater))
245 if face.image and face.image.name in tex :
246 self.file.write("%s,\n" % (tex.index(face.image.name) + count))
248 self.file.write("%s,\n" % (mater))
251 for mat in Material.Get():
252 self.file.write("{%s}\n"% (mat.name))
255 self.file.write("{Mat")
256 self.file.write("%s}\n"% (tex.index(mat) + 1))
257 self.file.write("}\n")
258 #***********************************************
260 #***********************************************
261 def writeMeshNormals(self,name,obj):
262 self.file.write(" MeshNormals {\n")
264 numvert=len(obj.verts)
265 self.file.write("%s;\n" % (numvert))
268 for vert in obj.verts:
270 if counter == numvert:
271 self.file.write("%s; %s; %s;;\n" % (vert.no[0], vert.no[1], vert.no[2]))
273 self.file.write("%s; %s; %s;,\n" % (vert.no[0], vert.no[1], vert.no[2]))
275 numfaces=len(obj.faces)
276 self.file.write("%s;\n" % (numfaces))
279 for face in obj.faces :
281 if counter == numfaces:
283 self.file.write("3; %s; %s; %s;;\n" % (face[0].index, face[1].index, face[2].index))
284 elif len(face.v) == 4:
285 self.file.write("4; %s; %s; %s; %s;;\n" % (face[0].index, face[1].index, face[2].index, face[3].index))
288 self.file.write("3; %s; %s; %s;,\n" % (face[0].index, face[1].index, face[2].index))
289 elif len(face.v) == 4 :
290 self.file.write("4; %s; %s; %s; %s;,\n" % (face[0].index, face[1].index, face[2].index, face[3].index))
291 self.file.write("}\n")
292 #***********************************************
294 #***********************************************
295 def writeMeshTextureCoords(self, name, obj):
297 self.file.write("MeshTextureCoords {\n")
301 for face in mesh.faces:
302 numvert = numvert + len(face.v)
303 self.file.write("%s;\n" % (numvert))
306 for face in mesh.faces:
309 self.file.write("%s;%s;,\n" % (mesh.faces[counter].uv[0][0], -mesh.faces[counter].uv[0][1]))
310 self.file.write("%s;%s;,\n" % (mesh.faces[counter].uv[1][0], -mesh.faces[counter].uv[1][1]))
311 self.file.write("%s;%s;,\n" % (mesh.faces[counter].uv[2][0], -mesh.faces[counter].uv[2][1]))
312 self.file.write("%s;%s;,\n" % (mesh.faces[counter].uv[3][0], -mesh.faces[counter].uv[3][1]))
313 elif len(face.v) == 3:
314 self.file.write("%s;%s;,\n" % (mesh.faces[counter].uv[0][0], -mesh.faces[counter].uv[0][1]))
315 self.file.write("%s;%s;,\n" % (mesh.faces[counter].uv[1][0], -mesh.faces[counter].uv[1][1]))
316 self.file.write("%s;%s;,\n" % (mesh.faces[counter].uv[2][0], -mesh.faces[counter].uv[2][1]))
318 self.file.write("}\n")
320 #***********************************************
322 #***********************************************
323 def writeFrames(self, name, obj):
324 matx = name.getMatrix()
325 self.file.write("Frame Fr_")
326 self.file.write("%s {\n" % (obj.name))
327 self.file.write(" FrameTransformMatrix {\n")
328 self.file.write(" %s,%s,%s,%s,\n" %
329 (round(matx[0][0],6),round(matx[0][1],6),round(matx[0][2],6),round(matx[0][3],6)))
330 self.file.write(" %s,%s,%s,%s,\n" %
331 (round(matx[1][0],6),round(matx[1][1],6),round(matx[1][2],6),round(matx[1][3],6)))
332 self.file.write(" %s,%s,%s,%s,\n" %
333 (round(matx[2][0],6),round(matx[2][1],6),round(matx[2][2],6),round(matx[2][3],6)))
334 self.file.write(" %s,%s,%s,%s;;\n" %
335 (round(matx[3][0],6),round(matx[3][1],6),round(matx[3][2],6),round(matx[3][3],6)))
336 self.file.write(" }\n")
337 #***********************************************
338 #WRITE ANIMATION KEYS
339 #***********************************************
340 def writeAnimation(self, name, obj):
341 startFr = Blender.Get('staframe')
342 endFr = Blender.Get('endframe')
343 self.file.write("AnimationSet animset_")
344 self.file.write("%s {\n" % (obj.name))
345 self.file.write(" Animation anim_")
346 self.file.write("%s { \n" % (obj.name))
347 self.file.write(" {Fr_")
348 self.file.write("%s }\n" % (obj.name))
349 self.file.write(" AnimationKey { \n")
350 self.file.write(" 0;\n")
351 self.file.write(" %s; \n" % (endFr))
352 for fr in range(startFr,endFr + 1) :
353 self.file.write(" %s; " % (fr))
354 self.file.write("4; ")
355 Blender.Set('curframe',fr)
360 quat = self.euler2quat(rot_x,rot_y,rot_z)
361 self.file.write("%s, %s, %s,%s;;" %
362 (quat[0],quat[1],quat[2],quat[3]))
364 self.file.write(";\n")
366 self.file.write(",\n")
367 self.file.write(" }\n")
368 self.file.write(" AnimationKey { \n")
369 self.file.write(" 2;\n")
370 self.file.write(" %s; \n" % (endFr))
371 for fr in range(startFr,endFr + 1) :
372 self.file.write(" %s; " % (fr))
373 self.file.write("3; ")
374 Blender.Set('curframe',fr)
376 self.file.write("%s, %s, %s;;" %
377 (loc[0],loc[1],loc[2]))
379 self.file.write(";\n")
381 self.file.write(",\n")
382 self.file.write(" }\n")
383 self.file.write(" AnimationKey { \n")
384 self.file.write(" 1;\n")
385 self.file.write(" %s; \n" % (endFr))
386 for fr in range(startFr,endFr + 1) :
387 self.file.write(" %s; " % (fr))
388 self.file.write("3; ")
389 Blender.Set('curframe',fr)
391 self.file.write("%s, %s, %s;;" %
392 (size[0],size[1],size[2]))
394 self.file.write(";\n")
396 self.file.write(",\n")
397 self.file.write(" }\n")
398 self.file.write(" }\n")
399 self.file.write(" }\n")
401 def euler2quat(self,rot_x,rot_y,rot_z):
413 quat_w = c_x * cy_cz - s_x * sy_sz
414 quat_x = s_x * cy_cz + c_x * sy_sz
415 quat_y = c_x * s_y * c_z - s_x * c_y * s_z
416 quat_z = c_x * c_y * s_z + s_x * s_y * c_z
418 return(quat_w,quat_x,quat_y,quat_z)
420 #***********************************************
422 #***********************************************
425 def my_callback(filename):
426 if filename.find('.x', -2) <= 0: filename += '.x' # add '.x' if the user didn't
427 xexport = xExport(filename)
428 arg = __script__['arg']
434 Blender.Window.FileSelector(my_callback, "Export DirectX")