- #!BPY
 - """
 - Name: 'DGL Wiki 2'
 - Blender: 241
 - Group: 'Export'
 - Tooltip: 'DGL Wiki Exporter 2'
 - """
 - import Blender
 - from Blender import NMesh
 - from Blender.BGL import *
 - from Blender.Draw import *
 - import math
 - from math import *
 - num_of_vertexgroups = Create(4)
 - TMenu = Create(1)
 - EVENT_NOEVENT = 1
 - EVENT_EXPORT = 2
 - EVENT_CANCEL = 3
 - def draw():
 - global num_of_vertexgroups,TMenu
 - global EVENT_NOEVENT,EVENT_EXPORT
 - glClear(GL_COLOR_BUFFER_BIT)
 - glRasterPos2d(10, 125)
 - Text("DGL Exporter Options")
 - TMemu = Menu("Normal|Normal+Tangent|TBN-Matrix",EVENT_NOEVENT,10,75,210,18, 1)
 - num_of_vertexgroups= Number("No of Vertgroups: ", EVENT_NOEVENT, 10, 55, 210, 18,num_of_vertexgroups.val, 0, 10, "Number of Vertgroups per Vertex");
 - Button("Export",EVENT_EXPORT, 140, 10, 80, 18)
 - Button("Cancel",EVENT_CANCEL, 10, 10, 80, 18)
 - def event(evt, val):
 - if (evt == QKEY and not val):
 - Exit()
 - def bevent(evt):
 - global EVENT_NOEVENT,EVENT_EXPORT
 - if (evt== EVENT_EXPORT):
 - Blender.Window.FileSelector(write, "Export")
 - elif (evt == EVENT_CANCEL):
 - Exit()
 - def minimum(a,b):
 - if (a<b):return a
 - return b
 - def maximum(a,b):
 - if (a>b):return a
 - return b
 - def quad2tri(msh):
 - flist=[]
 - for face in msh.faces:
 - if (len(face.v)==3):
 - flist += [face]
 - else:
 - d1 =(msh.verts[face.v[0].index].co.x - msh.verts[face.v[2].index].co.x) ** 2
 - d1+=(msh.verts[face.v[0].index].co.y - msh.verts[face.v[2].index].co.y) ** 2
 - d1+=(msh.verts[face.v[0].index].co.z - msh.verts[face.v[2].index].co.z) ** 2
 - d2 =(msh.verts[face.v[1].index].co.x - msh.verts[face.v[3].index].co.x) ** 2
 - d2+=(msh.verts[face.v[1].index].co.y - msh.verts[face.v[3].index].co.y) ** 2
 - d2+=(msh.verts[face.v[1].index].co.z - msh.verts[face.v[3].index].co.z) ** 2
 - if (d1<d2):
 - flist += [Blender.NMesh.Face([face.v[0],face.v[1],face.v[2]])]
 - flist[len(flist)-1].uv=[face.uv[0],face.uv[1],face.uv[2]]
 - flist[len(flist)-1].col=[face.col[0],face.col[1],face.col[2]]
 - flist[len(flist)-1].smooth=face.smooth
 - flist += [Blender.NMesh.Face([face.v[0],face.v[2],face.v[3]])]
 - flist[len(flist)-1].uv=[face.uv[0],face.uv[2],face.uv[3]]
 - flist[len(flist)-1].col=[face.col[0],face.col[1],face.col[2]]
 - flist[len(flist)-1].smooth=face.smooth
 - else:
 - flist += [Blender.NMesh.Face([face.v[0],face.v[1],face.v[3]])]
 - flist[len(flist)-1].uv=[face.uv[0],face.uv[1],face.uv[3]]
 - flist[len(flist)-1].col=[face.col[0],face.col[1],face.col[3]]
 - flist[len(flist)-1].smooth=face.smooth
 - flist += [Blender.NMesh.Face([face.v[1],face.v[2],face.v[3]])]
 - flist[len(flist)-1].uv=[face.uv[1],face.uv[2],face.uv[3]]
 - flist[len(flist)-1].col=[face.col[1],face.col[2],face.col[3]]
 - flist[len(flist)-1].smooth=face.smooth
 - msh.faces=flist
 - return msh
 - def createFaceTan(msh):
 - ftan = []
 - for face in msh.faces:
 - tan = msh.verts[face.v[2].index].co - msh.verts[face.v[0].index].co
 - #if (face.uv[2][1] != face.uv[1][1]):
 - m = (face.uv[2][1]-face.uv[0][1])/(face.uv[2][1]-face.uv[1][1])
 - tan += (msh.verts[face.v[1].index].co - msh.verts[face.v[2].index].co) * m
 - tan.normalize()
 - ftan += [tan]
 - return ftan
 - def createFaceBit(msh):
 - fbit = []
 - for face in msh.faces:
 - bit = msh.verts[face.v[1].index].co - msh.verts[face.v[0].index].co
 - #if (face.uv[1][0] != face.uv[2][0]):
 - m = (face.uv[1][0]-face.uv[0][0])/(face.uv[1][0]-face.uv[2][0])
 - bit += (msh.verts[face.v[2].index].co - msh.verts[face.v[1].index].co) * m
 - bit.normalize()
 - fbit += [bit]
 - return fbit
 - def interpolate(msh,ftan):
 - vtan = []
 - for vert in msh.verts:
 - vtan += [Blender.NMesh.Vert().co]
 - for face in msh.faces:
 - if (face.smooth == 1):
 - for vert in face.v:
 - vtan[vert.index] += ftan[vert.index]
 - for i in range(0,len(msh.verts)):
 - vtan[i].normalize()
 - return vtan
 - def octree(msh):
 - ### Boundingbox for Quad Octree
 - mini = msh.verts[0].co * 1.0
 - maxi = msh.verts[0].co * 1.0
 - for vert in msh.verts:
 - mini.x = minimum (mini.x,vert.co.x)
 - mini.y = minimum (mini.y,vert.co.y)
 - mini.z = minimum (mini.z,vert.co.z)
 - maxi.x = maximum (maxi.x,vert.co.x)
 - maxi.y = maximum (maxi.y,vert.co.y)
 - maxi.z = maximum (maxi.z,vert.co.z)
 - size = max (maxi.x-mini.x,maxi.y-mini.y,maxi.z-mini.z)
 - optindex = []
 - count = 0
 - for face in msh.faces:
 - center = msh.verts[0].co * 0.0
 - for vert in face.v:
 - center += msh.verts[vert.index].co
 - center *= 1.0 /( len(face.v) * size * 2.0)
 - center.x += 0.5
 - center.y += 0.5
 - center.z += 0.5
 - ix = int (center.x * 1023)
 - iy = int (center.y * 1023)
 - iz = int (center.z * 1023)
 - sortby = (ix&512)<<18 | (ix&256)<<16 |(ix&128)<<14 | (ix&64)<<12 |(ix&32)<<10 | (ix&16)<<8 |(ix&8)<<6 | (ix&4)<<4 |(ix&2)<<2 | (ix&1)<<0
 - sortby |= (iy&512)<<19 | (iy&256)<<17 |(iy&128)<<15 | (iy&64)<<13 |(iy&32)<<11 | (iy&16)<<9 |(iy&8)<<7 | (iy&4)<<5 |(iy&2)<<3 | (iy&1)<<1
 - sortby |= (iz&512)<<20 | (iz&256)<<18 |(iz&128)<<16 | (iz&64)<<14 |(iz&32)<<12 | (iz&16)<<10|(iz&8)<<8 | (iz&4)<<6 |(iz&2)<<4 | (iz&1)<<2
 - optindex += [(sortby,count)]
 - count += 1
 - optindex.sort()
 - flist=[]
 - for i in optindex:
 - flist += [msh.faces[i[1]]]
 - msh.faces=flist
 - return msh
 - def write(filename):
 - global num_of_vertexgroups,TMenu
 - out = file(filename, 'w')
 - obj = Blender.Object.GetSelected()[0]
 - msh = obj.getData()
 - msh = quad2tri(msh)
 - out.write('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n')
 - out.write('<vbo name="%s" verts="%i" type="GL_TRIANGLE">\n' % (msh.name, len(msh.faces)*3))
 - msh = octree(msh)
 - out.write('<vertices comp="3">\n')
 - for face in msh.faces:
 - for vert in face.v:
 - out.write( ' %f %f %f' % (msh.verts[vert.index].co.x, msh.verts[vert.index].co.y, msh.verts[vert.index].co.z))
 - out.write('\n')
 - out.write('</vertices>\n')
 - if (msh.hasFaceUV()==1):
 - out.write('<texturecoords comp="2">\n')
 - for face in msh.faces:
 - for vert in face.v:
 - out.write( ' %f %f %f %f %f %f\n' % (face.uv[0][0],face.uv[0][1],face.uv[1][0],face.uv[1][1],face.uv[2][0],face.uv[2][1]) )
 - out.write('</texturecoords>\n')
 - out.write('<normals>\n')
 - for face in msh.faces:
 - if (face.smooth==1):
 - for vert in face.v:
 - out.write( ' %f %f %f' % (msh.verts[vert.index].no.x, msh.verts[vert.index].no.y, msh.verts[vert.index].no.z))
 - out.write('\n')
 - else:
 - #Drei Normalvektoren für ein Solid Triangle
 - for vert in range(0,3):
 - out.write( ' %f, %f, %f,' % (face.no[0], face.no[1], face.no[2]))
 - out.write('\n')
 - out.write('</normals>\n')
 - #Aufbauen des Vertesguppenindexes
 - vertGroupData = []
 - groups = msh.getVertGroupNames()
 - for vert in msh.verts:
 - list = []
 - count = 1
 - for group in groups:
 - if (len(msh.getVertsFromGroup(group,0,[vert.index]))==1):
 - list += [(msh.getVertsFromGroup(group,1,[vert.index])[0][1],count)]
 - count += 1
 - list.sort()
 - list.reverse()
 - for i in range(0,num_of_vertexgroups.val):
 - list += [(0.0, 0)]
 - vertGroupData += [(list[0:num_of_vertexgroups.val])]
 - out.write('<vertexgroups comp="%i">\n' % num_of_vertexgroups.val)
 - out.write('<weight>\n')
 - for face in msh.faces:
 - for vert in face.v:
 - for group in vertGroupData[vert.index]:
 - out.write( ' %f' % (group[0]))
 - out.write('\n')
 - out.write('</weight>\n')
 - out.write('<index>\n')
 - for face in msh.faces:
 - for vert in face.v:
 - for group in vertGroupData[vert.index]:
 - out.write( ' %i' % (group[1]))
 - out.write('\n')
 - out.write('</index>\n')
 - out.write('</vertexgroups>\n')
 - ftan = createFaceTan(msh)
 - vtan = interpolate(msh,ftan)
 - fbit = createFaceBit(msh)
 - vbit = interpolate(msh,fbit)
 - out.write('<tan>\n')
 - for i in range(0,len(msh.faces)):
 - face = msh.faces[i]
 - if (face.smooth==1):
 - for vert in face.v:
 - out.write( ' %f %f %f' % (vtan[vert.index].x, vtan[vert.index].y, vtan[vert.index].z))
 - out.write('\n')
 - else:
 - for vert in range(0,3):
 - out.write( ' %f %f %f' % (ftan[i].x, ftan[i].y, ftan[i].z))
 - out.write('\n')
 - out.write('</tan>\n')
 - out.write('<bit>\n')
 - for i in range(0,len(msh.faces)):
 - face = msh.faces[i]
 - if (face.smooth==1):
 - for vert in face.v:
 - out.write( ' %f %f %f' % (vbit[vert.index].x, vbit[vert.index].y, vbit[vert.index].z))
 - out.write('\n')
 - else:
 - for vert in range(0,3):
 - out.write( ' %f %f %f' % (fbit[i].x, fbit[i].y, fbit[i].z))
 - out.write('\n')
 - out.write('</bit>\n')
 - out.write('<tbn>\n')
 - for i in range(0,len(msh.faces)):
 - face = msh.faces[i]
 - if (face.smooth==1):
 - for vert in face.v:
 - out.write( ' %f %f %f' % (vtan[vert.index].x, vtan[vert.index].y, vtan[vert.index].z))
 - out.write( ' %f %f %f' % (vbit[vert.index].x, vbit[vert.index].y, vbit[vert.index].z))
 - out.write( ' %f %f %f\n' % (msh.verts[vert.index].no.x, msh.verts[vert.index].no.y, msh.verts[vert.index].no.z))
 - else:
 - for vert in range(0,3):
 - out.write( ' %f %f %f' % (ftan[i].x, ftan[i].y, ftan[i].z))
 - out.write( ' %f %f %f' % (fbit[i].x, fbit[i].y, fbit[i].z))
 - out.write( ' %f %f %f\n' % (face.no[0], face.no[1], face.no[2]))
 - out.write('</tbn>\n')
 - out.write('</vbo>\n')
 - out.close()
 - Exit()
 - Register(draw, event, bevent)
 

