- #!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)