#---------------------------------------------------------------- # $Id: //src/racer/Mesh2DOF_227.py#2 $ #---------------------------------------------------------------- # This file may be copied. However, if you make improvements, # please send me a copy. # # Brent Burton # AustinMTB@yahoo.com # July 2003 # RaceSimCentral: vizor_atx #---------------------------------------------------------------- # # Convert a 2.27 Blender NMesh object to a DOF # file. This module needs the DOFfile module. # import string import Blender import DOFfile #---------------- # PRIVATE _DefineMaterial() def _DefineMaterial(dof1, mesh): # Assumption here is that a texture has been applied... imagename = string.split(mesh.faces[0].image.name, ".")[0] if imagename[0] == "_": imagename += ".bmp" else: imagename += ".tga" # Now convert the mesh material to MAT0 parts... if len(mesh.materials) > 0: mat = Blender.Material.Get(mesh.materials[0].name) mat0 = DOFfile.MAT0() dof1.addMAT0(mat0) mhdr = DOFfile.MHDR() mhdr.setName(mat.name) mat0.setMHDR(mhdr) mcol = DOFfile.MCOL() mcol.setAmbient([mat.R*mat.Amb, mat.G*mat.Amb, mat.B*mat.Amb, 0.0]) mcol.setDiffuse([mat.R, mat.G, mat.B, 0.0]) mcol.setSpecular([mat.specCol[0]*mat.Spec, mat.specCol[1]*mat.Spec, mat.specCol[2]*mat.Spec, 0.0]) mcol.setEmission([mat.R*mat.Emit, mat.G*mat.Emit, mat.B*mat.Emit, 0.0]) mcol.setShininess(mat.Hard) mat0.setMCOL(mcol) mcfl = DOFfile.MCFL() mat0.setMCFL(mcfl) muvw = DOFfile.MUVW() muvw.setUVOffset([0.0, 0.0]) muvw.setUVTiling([1.0, 1.0]) muvw.setAngle(0.0) muvw.setBlur(1.0) muvw.setBlurOffset(0.0) mat0.setMUVW(muvw) mtra = DOFfile.MTRA() mtra.setTransparency(1 - mat.Alpha) mtra.setBlendmode(0) mat0.setMTRA(mtra) mtex = DOFfile.MTEX() mtex.append(imagename) mat0.setMTEX(mtex) else: mat0 = DOFfile.MAT0() dof1.addMAT0(mat0) mhdr = DOFfile.MHDR() mhdr.setName("DummyMaterial") mat0.setMHDR(mhdr) mcol = DOFfile.MCOL() mcol.setAmbient([0.4, 0.4, 0.4, 0.0]) mcol.setDiffuse([0.8, 0.8, 0.8, 0.0]) mcol.setSpecular([0.5, 0.5, 0.5, 0.0]) mcol.setEmission([0.0, 0.0, 0.0, 0.0]) mcol.setShininess(15) mat0.setMCOL(mcol) mcfl = DOFfile.MCFL() mat0.setMCFL(mcfl) muvw = DOFfile.MUVW() muvw.setUVOffset([0.0, 0.0]) muvw.setUVTiling([1.0, 1.0]) muvw.setAngle(0.0) muvw.setBlur(1.0) muvw.setBlurOffset(0.0) mat0.setMUVW(muvw) mtra = DOFfile.MTRA() mtra.setTransparency(0.0) mtra.setBlendmode(0) mat0.setMTRA(mtra) mtex = DOFfile.MTEX() mtex.append(imagename) mat0.setMTEX(mtex) # end of material translation # Object coordinates are local. Each object's reference # point can be moved in Blender to translate the entire object. # Further, scaling can take place. Sooo, adjust XYZ # coords by appropriate scalings and translations. # TODO: do matrix rotations def _xformVertex(v, bobj): x = v[0] * bobj.SizeX + bobj.LocX y = v[1] * bobj.SizeY + bobj.LocY z = v[2] * bobj.SizeZ + bobj.LocZ # the (x, z, -y) is intentional as it converts # the modeler (3dsmax/blender) coordinate system # to OpenGL's. return [x, z, -y] def _xformNormal(n): # Ditto on the x,z,-y thing here return [n[0], n[2], -n[1]] def _getVColor(nmcol): # NMCol input r = nmcol.r / 255.0 g = nmcol.g / 255.0 b = nmcol.b / 255.0 return [r, g, b] #---------------- # PRIVATE ConvertMeshToDOF(): def _ConvertMeshToDOF(bobj, mesh): # Create the DOF. Then add a Material # and the geometry dof1 = DOFfile.DOF1() _DefineMaterial(dof1, mesh) # Make a geometric object, then populate it: gob1 = DOFfile.GOB1() dof1.addGOB1(gob1) # Make a header gob1.setGHDR( DOFfile.GHDR(0,0,0) ) # Iterate over the faces. Vertices have XYZ and UV data # separate in Blender; faces pick XYZ and UV values via # indices, and in Racer the XYZ/UV needs to be combined. # Since a single XYZ value can have numerous UV values # (in the case of corner (i.e. shared) vertices), the XYZ # values must be duplicated for as many faces that share them... dofverts = DOFfile.VERT() dofvcols = DOFfile.VCOL() dofuvs = DOFfile.TVER() dofnorms = DOFfile.NORM() dofindices = DOFfile.INDI() dofburst = DOFfile.BRST() verts = mesh.verts numOriginalVerts = len(verts) indexCount = 0 numTris = 0 for face in mesh.faces: corners = len(face.v) if corners >= 3: # add 1st tri: 0,1,2 # XYZ, Norm, UV dofverts.append(_xformVertex(verts[face.v[0].index].co, bobj)) dofnorms.append(_xformNormal(verts[face.v[0].index].no)) dofvcols.append(_getVColor(face.col[0])) dofuvs.append(face.uv[0]) idx0 = indexCount indexCount += 1 dofverts.append(_xformVertex(verts[face.v[1].index].co, bobj)) dofnorms.append(_xformNormal(verts[face.v[1].index].no)) dofvcols.append(_getVColor(face.col[1])) dofuvs.append(face.uv[1]) idx1 = indexCount indexCount += 1 dofverts.append(_xformVertex(verts[face.v[2].index].co, bobj)) dofnorms.append(_xformNormal(verts[face.v[2].index].no)) dofvcols.append(_getVColor(face.col[2])) dofuvs.append(face.uv[2]) idx2 = indexCount indexCount += 1 dofindices.append(idx0) dofindices.append(idx1) dofindices.append(idx2) numTris += 1 if corners == 4: # add 2nd tri: 2,3,0 dofverts.append(_xformVertex(verts[face.v[3].index].co, bobj)) dofnorms.append(_xformNormal(verts[face.v[3].index].no)) dofvcols.append(_getVColor(face.col[3])) dofuvs.append(face.uv[3]) idx3 = indexCount indexCount += 1 dofindices.append(idx2) # reuse dofindices.append(idx3) dofindices.append(idx0) # reuse numTris += 1 dofburst.addBurst(0, numTris * 9, 1, 3) # Done. Pass the arrays to the geom object. gob1.setVERT(dofverts) gob1.setVCOL(dofvcols) gob1.setNORM(dofnorms) gob1.setTVER(dofuvs) gob1.setINDI(dofindices) gob1.setBRST(dofburst) return dof1, numOriginalVerts, indexCount, numTris #---------------- # PUBLIC ExportMesh() def ExportMesh(bobj, directory): """Exports a Blender NMesh object to a DOF file in 'directory'.""" if str(type(bobj.data)) != "": print "Blender Object is not a NMesh" return mesh = bobj.data (dof1, vin, vout, tris) = _ConvertMeshToDOF(bobj, mesh) string.replace(directory, "\\", "/") lastChar = directory[len(directory)-1] if lastChar != "/": directory += "/" filename = directory + string.replace(bobj.name, ".", "") + ".dof" outf = file(filename, "wb") dof1.write(outf) outf.flush() outf.close() return (vin, vout, tris) #---------------- # PUBLIC ExportLayer() def ExportLayer(layer, directory): """Exports all mesh objects from a particular layer. If layer==-1, all mesh objects are exported. The resulting DOF files are stored in 'directory'. """ objs = Blender.Object.Get() numExported = 0 totalVin = 0 totalVout = 0 totalTris = 0 for obj in objs: if layer == -1 or layer == obj.Layer: mesh = obj.data if str(type(mesh)) == "": print "Exporting mesh " + obj.name (vin, vout, tris) = ExportMesh(obj, directory) print "---> Vin: %d Vout: %d Tris: %d" % (vin, vout, tris) totalVin += vin totalVout += vout totalTris += tris numExported += 1 print "%d meshes exported into %s" % (numExported, directory) print "Totals: Vin: %d Vout: %d Tris: %d" % (totalVin, totalVout, totalTris) # EOF