#!BPY """ Registration info for Blender menus: Name: 'DirectX(.x)...' Blender: 241 Group: 'Export' Tip: 'Export to DirectX text file format format.' """ __author__ = "Arben (Ben) Omari" __url__ = ("blender", "elysiun", "Author's site, http://www.omariben.too.it") __version__ = "3.0" __bpydoc__ = """\ This script exports a Blender mesh with armature to DirectX 8's text file format. Notes:
Check author's site or the elYsiun forum for a new beta version of the DX exporter. """ # DirectXExporter.py version 3.0 # Copyright (C) 2006 Arben OMARI -- omariarben@everyday.com # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # This script export meshes created with Blender in DirectX8 file format # it exports meshes,armatures,materials,normals,texturecoords and animations # Grab the latest version here :www.omariben.too.it import Blender from Blender import Types, Object, NMesh, Material,Armature,Mesh from Blender.Mathutils import * from Blender import Draw, BGL from Blender.BGL import * import math global mat_flip,index_list,space,bone_list,mat_dict global anim,flip_norm,swap_zy,flip_z,speed,ticks,no_light,recalc_norm,Bl_norm bone_list =[] index_list = [] mat_dict = {} space = 0;flip_z = 1;anim=0;swap_yz=0;flip_norm=0;speed=0;ticks= 25 Bl_norm = 1;recalc_norm = 0;no_light = 0 toggle_val = 0 toggle1_val = 0 toggle2_val = 0 toggle3_val = 1 toggle4_val = 0 toggle5_val = 1 toggle6_val = 0 toggle7_val = 0 anim_tick = Draw.Create(25) #*********************************************** # MAIN #*********************************************** def my_callback(filename): if filename.find('.x', -2) <= 0: filename += '.x' xexport = xExport(filename) xexport.SelectObjs() def my_callback_sel(filename): if filename.find('.x', -2) <= 0: filename += '.x' xexport = xExport(filename) xexport.exportSelMesh() def event(evt, val): if evt == Draw.ESCKEY: Draw.Exit() return def button_event(evt): global toggle_val,toggle1_val,toggle2_val,toggle3_val,toggle4_val,toggle5_val,toggle6_val,toggle7_val global flip_z,swap_yz,flip_norm,anim,ticks,speed,no_light,Bl_norm,recalc_norm arg = __script__['arg'] if evt == 1: toggle_val = 1 - toggle_val anim = toggle_val Draw.Redraw(1) if evt == 2: toggle1_val = 1 - toggle1_val flip_norm = toggle1_val Draw.Redraw(1) if evt == 3: toggle2_val = 1 - toggle2_val swap_yz = toggle2_val Draw.Redraw(1) if evt == 4: toggle3_val = 1 - toggle3_val flip_z = toggle3_val Draw.Redraw(1) if evt == 5: toggle4_val = 1 - toggle4_val speed = toggle4_val Draw.Redraw(1) if evt == 10: toggle5_val = 1 - toggle5_val if toggle5_val==1: toggle6_val = 0 toggle7_val = 0 else : toggle6_val = 1 toggle7_val = 1 no_light = toggle7_val recalc_norm = toggle6_val Bl_norm = toggle5_val Draw.Redraw(1) if evt == 11: toggle6_val = 1 - toggle6_val if toggle6_val==1: toggle5_val = 0 toggle7_val = 0 else : toggle5_val = 1 toggle7_val = 1 no_light = toggle7_val recalc_norm = toggle6_val Bl_norm = toggle5_val Draw.Redraw(1) if evt == 12: toggle7_val = 1 - toggle7_val if toggle7_val==1: toggle6_val = 0 toggle5_val = 0 else : toggle6_val = 1 toggle5_val = 1 no_light = toggle7_val recalc_norm = toggle6_val Bl_norm = toggle5_val Draw.Redraw(1) if evt == 6: ticks = anim_tick.val if evt == 7: fname = Blender.sys.makename(ext = ".x") Blender.Window.FileSelector(my_callback, "Export DirectX", fname) if evt == 8: fname = Blender.sys.makename(ext = ".x") Blender.Window.FileSelector(my_callback_sel, "Export DirectX", fname) if evt == 9: Draw.Exit() def draw(): global animsg,flipmsg,swapmsg,anim_tick global flip_z,swap_yz,flip_norm,anim,ticks,speed,recalc_norm,Bl_norm,no_light glClearColor(0.55,0.6,0.6,1) glClear(BGL.GL_COLOR_BUFFER_BIT) #external box glColor3f(0.2,0.3,0.3) rect(10,402,300,382) #-- #glColor3f(0.3,0.4,0.4) #rect(11,399,298,398) #-- glColor3f(0.5,0.75,0.65) rect(14,398,292,30) #-- glColor3f(0.5,0.75,0.65) rect(14,366,292,160) #-- glColor3f(0.5,0.75,0.65) rect(14,202,292,60) #-- glColor3f(0.5,0.75,0.65) rect(14,138,292,40) #-- glColor3f(0.5,0.75,0.65) rect(14,94,292,70) glColor3f(0.8,.8,0.6) glRasterPos2i(20, 380) Draw.Text("DirectX Exporter ",'large') Draw.Text("(for Blender 2.41)", 'small') #-------Aniamtion toggle--------------------------------------------- Draw.Toggle("Anim", 1, 20, 330, 55, 20, toggle_val,"export animations") if toggle_val : anim = 1 animsg = "animation will be exported" else: anim = 0 animsg = "animation will be not exported" glRasterPos2i(100,335) Draw.Text(animsg) #---Flip normals toggle----------------------------------------------- Draw.Toggle("Flip norm", 2, 20, 300, 55, 20, toggle1_val,"invert normals") if toggle1_val : flip_norm = 1 flipmsg = "flipped normals" else: flip_norm = 0 flipmsg = "not flipped normals" glRasterPos2i(100,305) Draw.Text(flipmsg) #------Swap yz toggle---------------------------------------------------------------- Draw.Toggle("Swap zy", 3, 20, 270, 55, 20, toggle2_val,"swap z,y axis(y up)") if toggle2_val : swap_yz = 1 swapmsg = "Y-axis up" else: swap_yz = 0 swapmsg = "Z-axis up" glRasterPos2i(100,275) Draw.Text(swapmsg) #------Flip z toggle---------------------------------------------------------------- Draw.Toggle("Flip z", 4, 20, 240, 55, 20, toggle3_val,"flip z axis") if toggle3_val : flip_z = 1 zmsg = "left handed system" else: flip_z = 0 zmsg = "right handed system" glRasterPos2i(100,245) Draw.Text(zmsg) #------Speed toggle---------------------------------------------------------------- Draw.Toggle("Speed", 5, 20, 210, 55, 20, toggle4_val,"Animation speed") if toggle4_val : speed = 1 spedmsg = "set speed" anim_tick = Draw.Number("", 6,200, 210, 85, 20, anim_tick.val,1,100000,"ticks per second") else: speed = 0 spedmsg = "" glRasterPos2i(100,215) Draw.Text(spedmsg) #------Blender Normals toggle---------------------------------------------------------------- Draw.Toggle("Bl.normals", 10, 20, 105, 75, 25, toggle5_val,"export normals as in Blender") if toggle5_val : Bl_norm = 1 #------Recalculute Normals toggle---------------------------------------------------------------- Draw.Toggle("recalc.no", 11, 120, 105, 75, 25, toggle6_val,"export recalculated normals") if toggle6_val : recalc_norm = 1 #------Recalculute Normals toggle---------------------------------------------------------------- Draw.Toggle("no smooth", 12, 220, 105, 75, 25, toggle7_val,"every vertex has the face normal,no smoothing") if toggle7_val : no_light = 1 #------Draw Button export---------------------------------------------------------------- exp_butt = Draw.Button("Export All",7,20, 155, 75, 30, "export all the scene objects") sel_butt = Draw.Button("Export Sel",8,120, 155, 75, 30, "export the selected object") exit_butt = Draw.Button("Exit",9,220, 155, 75, 30, "exit") glRasterPos2i(20,75) Draw.Text("(C) 2006 Arben OMARI ") glRasterPos2i(20,55) Draw.Text("http://www.omariben.too.it") glRasterPos2i(20,35) Draw.Text("aromar@tin.it") def rect(x,y,width,height): glBegin(GL_LINE_LOOP) glVertex2i(x,y) glVertex2i(x+width,y) glVertex2i(x+width,y-height) glVertex2i(x,y-height) glEnd() def rectFill(x,y,width,height): glBegin(GL_POLYGON) glVertex2i(x,y) glVertex2i(x+width,y) glVertex2i(x+width,y-height) glVertex2i(x,y-height) glEnd() Draw.Register(draw, event, button_event) #*********************************************** #*********************************************** # EXPORTER #*********************************************** #*********************************************** class xExport: def __init__(self, filename): self.file = open(filename, "w") #********************************************************************************************************************************************* #*********************************************** #Select Scene objects #*********************************************** def analyzeScene(self): parent_list = [] for obj in Object.Get(): mesh = obj.getData() if type(mesh) == Types.ArmatureType or type(mesh) == Types.NMeshType or obj.getType() == "Empty": pare = obj.getParent() if pare == None : parent_list.append(obj) return parent_list def getChildren(self,obj): children_list = [] for object in Object.Get(): pare = object.parent if pare == obj : children_list.append(object) return children_list def getArmChildren(self,obj): for object in Object.Get(): pare = object.parent if pare == obj : return object def getLocMat(self, obj): pare = obj.getParent() mat = obj.matrixWorld mat_id = Matrix([1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]) if pare: mat_p = pare.matrixWorld mat_c = Matrix(mat_p) mat_c.invert() mat_f = mat * mat_c else : mat_id.invert() mat_f = mat * mat_id return mat_f def writeObjFrames(self,obj): global space,chld_obj,ch_list mesh = obj.getData() if obj.getType() == "Empty" : mat = self.getLocMat(obj) mat_c = Matrix(mat) name = obj.name name_f = name.replace(".","") self.writeArmFrames(mat_c, name_f) if type(mesh) == Types.ArmatureType : Child_obj = self.getArmChildren(obj) chld_obj = obj ch_list.append(Child_obj) self.writeRootBone(obj, Child_obj) if type(mesh) == Types.NMeshType and obj not in ch_list: self.exportMesh(obj) def writeChildObj(self,obj): global space,ch_list space += 1 if obj : for ob in obj: if ob not in ch_list: self.writeObjFrames(ob) ch_list.append(ob) ch_ob = self.getChildren(ob) self.writeChildObj(ch_ob) self.closeBrackets() self.file.write(" // End of the Object %s \n" % (ob.name)) def writeRootFrame(self): global flip_z,swap_yz,speed if speed: self.writeAnimTicks() if flip_z: mat_flip = Matrix([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]) else : mat_flip = Matrix([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]) if swap_yz : mat_rot = RotationMatrix(-90, 4, 'x') mat_flip = mat_rot * mat_flip self.writeArmFrames(mat_flip, "RootFrame") ################################################################## def SelectObjs(self): global space,chld_obj,ch_list,flip_z,swap_yz,speed print "exporting..." self.writeHeader() self.writeRootFrame() obj_list = self.analyzeScene() space += 1 ch_list = [] for obj in obj_list: self.writeObjFrames(obj) ch_l = self.getChildren(obj) for ch in ch_l: if ch and ch.getType() == "Armature": ch_list.append(ch) self.writeObjFrames(ch) else : self.writeChildObj(ch_l) if obj.getType() != "Armature": self.file.write(" } // SI End of the Object %s \n" % (obj.name)) self.file.write("} // End of the Root Frame\n") if anim : self.file.write("AnimationSet {\n") for obj in Object.Get(): mesh = obj.getData() if type(mesh) == Types.NMeshType or obj.getType() == "Empty": ip_list = obj.getIpo() if ip_list != None : self.writeAnimationObj(obj) elif type(mesh) == Types.ArmatureType : act_list = obj.getAction() if act_list != None : self.writeAnimation(obj) #ip_list = obj.getIpo() #if ip_list != None : # self.writeAnimationObj(obj) self.file.write("} // End of Animation Set\n") self.writeEnd() ####################################################### def writeAnimTicks(self): global ticks self.file.write("AnimTicksPerSecond {\n") self.file.write("%d; \n" % (ticks)) self.file.write("}\n") #*********************************************** #Export Mesh without Armature #*********************************************** def exportMesh(self, obj): tex = [] mesh = obj.getData() self.writeTextures(obj, tex) self.writeMeshcoordArm(obj, arm_ob = None) self.writeMeshMaterialList(obj, mesh, tex) self.writeMeshNormals(obj, mesh) self.writeMeshTextureCoords(obj, mesh) self.file.write(" } // End of the Frame %s \n" % (obj.name)) #*********************************************** #Export the Selected Mesh #*********************************************** def exportSelMesh(self): print "exporting ..." self.writeHeader() self.writeRootFrame() tex = [] obj = Object.GetSelected()[0] mesh = obj.getData() if type(mesh) == Types.NMeshType : self.writeTextures(obj, tex) self.writeMeshcoordArm(obj, arm_ob = None) self.writeMeshMaterialList(obj, mesh, tex) self.writeMeshNormals(obj, mesh) self.writeMeshTextureCoords(obj, mesh) self.file.write(" }\n") self.file.write("}\n") self.file.write("}\n") ip_list = obj.getIpo() if ip_list != None : self.file.write("AnimationSet {\n") self.writeAnimationObj(obj) self.file.write("}\n") print "exporting ..." else : print "The selected object is not a mesh" print "...finished" #*********************************************** #Export Mesh with Armature #*********************************************** def exportMeshArm(self,arm,arm_ob,ch_obj): tex = [] mesh = ch_obj.getData() self.writeTextures(ch_obj, tex) self.writeMeshcoordArm(ch_obj ,arm_ob) self.writeMeshMaterialList(ch_obj, mesh, tex) self.writeMeshNormals(ch_obj, mesh) self.writeMeshTextureCoords(ch_obj, mesh) self.writeSkinWeights(arm,mesh) #self.file.write(" } // End of the Frame %s \n" % (ch_obj.name)) self.file.write(" } // End of the Object %s \n" % (ch_obj.name)) #*********************************************** #Export Root Bone #*********************************************** def writeRootBone(self, chld_obj, child_obj): global space,root_bon arms = chld_obj.getData() mat_arm = self.getLocMat(chld_obj) for bon in arms.bones.values(): if bon.hasParent(): pass else: root_bon = bon space += 1 mat_r = self.writeAnimCombineMatrix(root_bon,1) name_r = root_bon.name name_f = name_r.replace(".","") self.writeArmFrames(mat_r, name_f) bon_c = root_bon.children self.writeChildren(bon_c) self.file.write(" } // End of the Bone %s \n" % (root_bon.name)) self.exportMeshArm(arms, chld_obj ,child_obj) #*********************************************** #Create Children structure #*********************************************** def writeBon(self,bon): global space mat_r = self.writeAnimCombineMatrix(bon,1) name_r = bon.name name_f = name_r.replace(".","") self.writeArmFrames(mat_r, name_f) def writeChildren(self,bon_c): global space,bone_list space += 1 if bon_c: for bo in bon_c: if bo.name not in bone_list: self.writeBon(bo) bone_list.append(bo.name) bo_c = bo.children self.writeChildren(bo_c) self.closeBrackets() def closeBrackets(self): global space space = space-1 tab = " " self.file.write("%s" % (tab * space)) self.file.write("}\n") #*********************************************** #Offset Matrix #*********************************************** def writeMatrixOffset(self,bon): global chld_obj Blender.Set('curframe', 1) pose = chld_obj.getPose() pos_b = pose.bones[bon.name] mat_b = pos_b.poseMatrix mat_c = Matrix(mat_b) mat_c.invert() return mat_c #*********************************************** #Combine Matrix #*********************************************** def writeCombineMatrix(self,bon): global chld_obj Blender.Set('curframe', 1) pose = chld_obj.getPose() pos_b = pose.bones[bon.name] mat_b = pos_b.poseMatrix if bon.hasParent(): pare = bon.parent pos_p = pose.bones[pare.name] mat_p = pos_p.poseMatrix else: mat_p = Matrix([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]) mat_c = Matrix(mat_p) mat_c.invert() mat_f = mat_b * mat_c return mat_f #*********************************************** #Combine Matrix #*********************************************** def writeAnimCombineMatrix(self,bon,fre): global chld_obj Blender.Set('curframe', fre) pose = chld_obj.getPose() pos_b = pose.bones[bon.name] mat_b = pos_b.poseMatrix if bon.hasParent(): pare = bon.parent pos_p = pose.bones[pare.name] mat_p = pos_p.poseMatrix else: mat_p = Matrix([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]) mat_c = Matrix(mat_p) mat_c.invert() mat_f = mat_b * mat_c return mat_f #********************************************************************************************************************************************* #*********************************************** #Write SkinWeights #*********************************************** def writeSkinWeights(self, arm, mesh): global index_list v_dict = {} Blender.Set('curframe',1) self.file.write(" XSkinMeshHeader {\n") max_infl = 0 for bo in arm.bones.values() : name = bo.name try : vertx_list = mesh.getVertsFromGroup(name,1) for inde in vertx_list : vert_infl = mesh.getVertexInfluences(inde[0]) ln_infl = len(vert_infl) if ln_infl > max_infl : max_infl = ln_infl except: pass self.file.write(" %d; \n" % (max_infl)) self.file.write(" %d; \n" % (max_infl * 3)) self.file.write(" %d; \n" % (len(arm.bones.values()))) self.file.write(" }\n") for bo in arm.bones.values() : bo_list = [] weight_list = [] name = bo.name f_name = name.replace(".","") try : vert_list = mesh.getVertsFromGroup(name,1) le = 0 for indx in vert_list: ver_infl = mesh.getVertexInfluences(indx[0]) infl = 0.0 if len(ver_infl) != 0: sum = 0.0 for bone_n, weight in ver_infl: if bone_n == name: infl = weight sum += weight infl /= sum i = -1 for el in index_list : i += 1 if el == indx[0] : le +=1 bo_list.append(i) weight_list.append(infl) self.file.write(" SkinWeights {\n") self.file.write(' "%s"; \n' % (f_name)) self.file.write(' %d; \n' % (le)) count = 0 for ind in bo_list : count += 1 if count == len(bo_list): self.file.write(" %d; \n" % (ind)) else : self.file.write(" %d, \n" % (ind)) cou = 0 for wegh in weight_list : cou += 1 if cou == len(weight_list): self.file.write(" %f; \n" % (round(wegh,6))) else : self.file.write(" %f, \n" % (round(wegh,6))) matx = self.writeMatrixOffset(bo) self.writeOffsFrames(matx, name) except : pass self.file.write(" } // End of XSkinMeshHeader\n") #*********************************************** # Write Matrices #*********************************************** def writeArmFrames(self, matx, name): global space tab = " " self.file.write("%s" % (tab * space)) self.file.write("Frame ") self.file.write("%s {\n\n" % (name)) self.file.write("%s" % (tab * space)) self.file.write(" FrameTransformMatrix {\n") self.writeFrame(matx) #*********************************************** # Write Frames #*********************************************** def writeOffsFrames(self, matx, name): space = 1 self.writeFrame(matx) #*********************************************** # Write Frames #*********************************************** def writeFrame(self, matx): tab = " " self.file.write("%s" % (tab * space)) self.file.write(" %f,%f,%f,%f,\n" % (round(matx[0][0],4),round(matx[0][1],4),round(matx[0][2],4),round(matx[0][3],4))) self.file.write("%s" % (tab * space)) self.file.write(" %f,%f,%f,%f,\n" % (round(matx[1][0],4),round(matx[1][1],4),round(matx[1][2],4),round(matx[1][3],4))) self.file.write("%s" % (tab * space)) self.file.write(" %f,%f,%f,%f,\n" % (round(matx[2][0],4),round(matx[2][1],4),round(matx[2][2],4),round(matx[2][3],4))) self.file.write("%s" % (tab * space)) self.file.write(" %f,%f,%f,%f;;\n" % (round(matx[3][0],4),round(matx[3][1],4),round(matx[3][2],4),round(matx[3][3],4))) self.file.write("%s" % (tab * space)) self.file.write(" }\n") #********************************************************************************************************************************************* #*********************************************** #HEADER #*********************************************** def writeHeader(self): self.file.write("xof 0303txt 0032\n\n\n") self.file.write("template VertexDuplicationIndices { \n\ \n\ DWORD nIndices;\n\ DWORD nOriginalVertices;\n\ array DWORD indices[nIndices];\n\ }\n\ template XSkinMeshHeader {\n\ <3cf169ce-ff7c-44ab-93c0-f78f62d172e2>\n\ WORD nMaxSkinWeightsPerVertex;\n\ WORD nMaxSkinWeightsPerFace;\n\ WORD nBones;\n\ }\n\ template SkinWeights {\n\ <6f0d123b-bad2-4167-a0d0-80224f25fabb>\n\ STRING transformNodeName;\n\ DWORD nWeights;\n\ array DWORD vertexIndices[nWeights];\n\ array float weights[nWeights];\n\ Matrix4x4 matrixOffset;\n\ }\n\n") #*********************************************** #CLOSE FILE #*********************************************** def writeEnd(self): self.file.close() print "... finished" #*********************************************** #EXPORT TEXTURES #*********************************************** def writeTextures(self,name, tex): mesh = name.data for face in mesh.faces: if face.image and face.image.name not in tex: tex.append(face.image.name) #*********************************************** #EXPORT MESH DATA with Armature #*********************************************** def writeMeshcoordArm(self, obj ,arm_ob): global index_list,flip_z #TransformMatrix mat = self.getLocMat(obj) name_f = obj.name.replace(".","") self.writeArmFrames(mat, name_f) mesh = NMesh.GetRawFromObject(obj.name) self.file.write("Mesh {\n") numface=len(mesh.faces) #VERTICES NUMBER numvert = 0 for face in mesh.faces: numvert = numvert + len(face.v) self.file.write("%d;\n" % (numvert)) if numvert == 0: print "Mesh named",mesh.name,"has no vertices.Problems may occur using the .x file" #VERTICES COORDINATES counter = 0 for face in mesh.faces: counter += 1 for n in range(len(face.v)): index_list.append(face.v[n].index) vec_vert = Vector([(face.v[n].co[0]), face.v[n].co[1], face.v[n].co[2], 1]) if arm_ob : f_vec_vert = vec_vert * mat else : f_vec_vert = vec_vert self.file.write("%f; %f; %f;" % (round(f_vec_vert[0],4), round(f_vec_vert[1],4), round(f_vec_vert[2],4))) if counter == numface : if n == len(face.v)-1 : self.file.write(";\n") else : self.file.write(",\n") else : self.file.write(",\n") if flip_z: a3 = 0;b3 = 2;c3 = 1 a4 = 0;b4 = 3;c4 = 2;d4 = 1 else: a3 = 0;b3 = 1;c3 = 2 a4 = 0;b4 = 1;c4 = 2;d4 = 3 #FACES NUMBER self.file.write("%s;\n" % (numface)) coun,counter = 0, 0 for face in mesh.faces : coun += 1 if coun == numface: if len(face.v) == 3: self.file.write("3; %d, %d, %d;;\n" % (counter + a3, counter + b3, counter + c3)) counter += 3 elif len(face.v) == 4: self.file.write("4; %d, %d, %d, %d;;\n" % (counter + a4, counter + b4, counter + c4, counter + d4)) counter += 4 elif len(face.v) < 3: print "WARNING:the mesh has faces with less then 3 vertices" print " It my be not exported correctly." else: if len(face.v) == 3: self.file.write("3; %d, %d, %d;,\n" % (counter + a3, counter + b3, counter + c3)) counter += 3 elif len(face.v) == 4: self.file.write("4; %d, %d, %d, %d;,\n" % (counter + a4, counter + b4, counter + c4, counter + d4)) counter += 4 elif len(face.v) < 3: print "WARNING:the mesh has faces with less then 3 vertices" print " It my be not exported correctly." #*********************************************** #MESH MATERIAL LIST #*********************************************** def writeMeshMaterialList(self, obj, mesh, tex): self.file.write(" MeshMaterialList {\n") #HOW MANY MATERIALS ARE USED count = 0 for mat in mesh.getMaterials(): count+=1 self.file.write(" %d;\n" % (len(tex) + count)) #HOW MANY FACES IT HAS numfaces=len(mesh.faces) self.file.write(" %d;\n" % (numfaces)) ##MATERIALS INDEX FOR EVERY FACE counter = 0 for face in mesh.faces : counter += 1 mater = face.materialIndex if counter == numfaces: if face.image and face.image.name in tex : self.file.write(" %d;;\n" % (tex.index(face.image.name) + count)) else : self.file.write(" %d;;\n" % (mater)) else : if face.image and face.image.name in tex : self.file.write(" %d,\n" % (tex.index(face.image.name) + count)) else : self.file.write(" %d,\n" % (mater)) ##MATERIAL NAME for mat in mesh.getMaterials(): self.file.write(" Material") name_m = mat.name name_f = name_m.replace(".","") self.file.write(" %s "% (name_f)) self.file.write("{\n") self.file.write(" %f; %f; %f;" % (mat.R, mat.G, mat.B)) self.file.write("%s;;\n" % (mat.alpha)) self.file.write(" %f;\n" % (mat.spec)) self.file.write(" %f; %f; %f;;\n" % (mat.specR, mat.specG, mat.specB)) self.file.write(" 0.0; 0.0; 0.0;;\n") self.file.write(" } //End of Material\n") for mat in tex: self.file.write(" Material Mat") self.file.write("%s "% (len(tex))) self.file.write("{\n") self.file.write(" 1.0; 1.0; 1.0; 1.0;;\n") self.file.write(" 1.0;\n") self.file.write(" 1.0; 1.0; 1.0;;\n") self.file.write(" 0.0; 0.0; 0.0;;\n") self.file.write(" TextureFilename {") self.file.write(' "%s";'% (mat)) self.file.write(" }\n") self.file.write(" } // End of Material\n") self.file.write(" } //End of MeshMaterialList\n") #*********************************************** #MESH NORMALS #*********************************************** def writeMeshNormals(self,name,mesh): global flip_norm,flip_z,no_light,recalc_norm,Bl_norm self.file.write(" MeshNormals {\n") #VERTICES NUMBER numvert = 0 for face in mesh.faces: numvert = numvert + len(face.v) self.file.write("%d;\n" % (numvert)) numfaces=len(mesh.faces) if flip_norm : fl = -1 else : fl = 1 #VERTICES NORMAL if Bl_norm: self.writeBlenderNormals(mesh,fl) if recalc_norm: self.writeRecalcNormals(mesh,fl) if no_light: self.writeNoSmothing(mesh,fl) if flip_z: a3 = 0;b3 = 2;c3 = 1 a4 = 0;b4 = 3;c4 = 2;d4 = 1 else: a3 = 0;b3 = 1;c3 = 2 a4 = 0;b4 = 1;c4 = 2;d4 = 3 #FACES NUMBER self.file.write("%s;\n" % (numfaces)) coun,counter = 0, 0 for face in mesh.faces : coun += 1 if coun == numfaces: if len(face.v) == 3: self.file.write("3; %d, %d, %d;;\n" % (counter + a3, counter + b3, counter + c3)) counter += 3 else : self.file.write("4; %d, %d, %d, %d;;\n" % (counter + a4, counter + b4, counter + c4, counter + d4)) counter += 4 else: if len(face.v) == 3: self.file.write("3; %d, %d, %d;,\n" % (counter + a3, counter + b3, counter + c3)) counter += 3 else : self.file.write("4; %d, %d, %d, %d;,\n" % (counter + a4, counter + b4, counter + c4, counter + d4)) counter += 4 self.file.write("} //End of MeshNormals\n") def writeBlenderNormals(self,mesh,fl): numfaces=len(mesh.faces) #VERTICES NORMAL counter = 0 for face in mesh.faces: counter += 1 for n in range(len(face.v)): self.file.write(" %f; %f; %f;" % ( (round(face.v[n].no[0],6)*fl),(round(face.v[n].no[1],6)*fl),(round(face.v[n].no[2],6)*fl))) if counter == numfaces : if n == len(face.v)-1 : self.file.write(";\n") else : self.file.write(",\n") else : self.file.write(",\n") def writeRecalcNormals(self,mesh,fl): numfaces=len(mesh.faces) normal_list = {} idx = 0 for vertex in mesh.verts: v_norm = Vector([0, 0, 0]) normal_list[idx] = v_norm idx += 1 for face in mesh.faces: for verts in face.v: if verts.index == vertex.index : v_norm[0] += face.no[0] v_norm[1] += face.no[1] v_norm[2] += face.no[2] v_norm.normalize() counter = 0 for face in mesh.faces: counter += 1 n = 0 for vert in face.v: n += 1 norm = normal_list[vert.index] self.file.write(" %f; %f; %f;" % ( (round(norm[0],6)*fl),(round(norm[1],6)*fl),(round(norm[2],6)*fl))) if counter == numfaces : if n == len(face.v) : self.file.write(";\n") else : self.file.write(",\n") else : self.file.write(",\n") def writeNoSmothing(self,mesh,fl): numfaces=len(mesh.faces) counter = 0 for face in mesh.faces: counter += 1 n = 0 for n in range(len(face.v)): n += 1 self.file.write(" %f; %f; %f;" % ( (round(face.no[0],6)*fl),(round(face.no[1],6)*fl),(round(face.no[2],6)*fl))) if counter == numfaces : if n == len(face.v) : self.file.write(";\n") else : self.file.write(",\n") else : self.file.write(",\n") #*********************************************** #MESH TEXTURE COORDS #*********************************************** def writeMeshTextureCoords(self, name, mesh): if mesh.hasFaceUV(): self.file.write("MeshTextureCoords {\n") #VERTICES NUMBER numvert = 0 for face in mesh.faces: numvert += len(face.v) self.file.write("%d;\n" % (numvert)) #UV COORDS numfaces = len(mesh.faces) counter = -1 co = 0 for face in mesh.faces: counter += 1 co += 1 for n in range(len(face.v)): self.file.write("%f;%f;" % (mesh.faces[counter].uv[n][0], -mesh.faces[counter].uv[n][1])) if co == numfaces : if n == len(face.v) - 1 : self.file.write(";\n") else : self.file.write(",\n") else : self.file.write(",\n") self.file.write("} //End of MeshTextureCoords\n") #***********************************************#***********************************************#*********************************************** #*********************************************** #FRAMES #*********************************************** def writeFrames(self, matx): self.file.write("%f,%f,%f,%f," % (round(matx[0][0],4),round(matx[0][1],4),round(matx[0][2],4),round(matx[0][3],4))) self.file.write("%f,%f,%f,%f," % (round(matx[1][0],4),round(matx[1][1],4),round(matx[1][2],4),round(matx[1][3],4))) self.file.write("%f,%f,%f,%f," % (round(matx[2][0],4),round(matx[2][1],4),round(matx[2][2],4),round(matx[2][3],4))) self.file.write("%f,%f,%f,%f;;" % (round(matx[3][0],4),round(matx[3][1],4),round(matx[3][2],4),round(matx[3][3],4))) #*********************************************** #WRITE ANIMATION KEYS #*********************************************** def writeAnimation(self,arm_ob): global mat_dict, root_bon arm = arm_ob.getData() act_list = arm_ob.getAction() ip = act_list.getAllChannelIpos() for bon in arm.bones.values() : point_list = [] name = bon.name name_f = name.replace(".", "") try : ip_bon_channel = ip[bon.name] ip_bon_name = ip_bon_channel.getName() ip_bon = Blender.Ipo.Get(ip_bon_name) poi = ip_bon.getCurves() for po in poi[3].getPoints(): a = po.getPoints() point_list.append(int(a[0])) #point_list.pop(0) self.file.write(" Animation { \n") self.file.write(" { %s }\n" %(name_f)) self.file.write(" AnimationKey { \n") self.file.write(" 4;\n") self.file.write(" %d; \n" % (len(point_list))) for fr in point_list: if name == root_bon.name : mat_b = self.writeAnimCombineMatrix(bon,fr) mat_arm = self.getLocMat(arm_ob) mat = mat_b * mat_arm else: mat = self.writeAnimCombineMatrix(bon,fr) self.file.write(" %d;" % (fr)) self.file.write("16;") self.writeFrames(mat) if fr == point_list[len(point_list)-1]: self.file.write(";\n") else: self.file.write(",\n") self.file.write(" }\n") self.file.write(" }\n") self.file.write("\n") except: pass #*********************************************** #WRITE ANIMATION KEYS #*********************************************** def writeAnimationObj(self, obj): point_list = [] ip = obj.getIpo() poi = ip.getCurves() for po in poi[0].getPoints(): a = po.getPoints() point_list.append(int(a[0])) name = obj.name name_f = name.replace(".", "") self.file.write(" Animation {\n") self.file.write(" { ") self.file.write("%s }\n" % (name_f)) self.file.write(" AnimationKey { \n") self.file.write(" 4;\n") self.file.write(" %d; \n" % (len(point_list))) for fr in point_list: self.file.write(" %d;" % (fr)) self.file.write("16;") Blender.Set('curframe',fr) #mat_new = self.getLocMat(obj) mat_new = obj.matrixLocal self.writeFrames(mat_new) if fr == point_list[len(point_list)-1]: self.file.write(";\n") else: self.file.write(",\n") self.file.write(" }\n") self.file.write(" }\n") #***********************************************#***********************************************#***********************************************