#!BPY

"""
Name: 'BX Export'
Blender: 240
Group: 'Export'
Tip: 'Export BX Object file format (*.bxo)'
"""

#NOTE: to add this script to Blender's export menu, go to blender options and set the 'script path' to this file's directory and click the update button.


print( "=========SCRIPTSTART=========" )

import Blender
from Blender import NMesh
from Blender import Mathutils
import struct, string, types
import bpy
import math
import random

status = 0
status1 = 0
status1m = 0

def draw():     # Define the draw function (which draws your GUI).
				Blender.BGL.glClear(Blender.BGL.GL_COLOR_BUFFER_BIT) # This clears the window
				#buttons
				Blender.Draw.Button("Write Map",1,4,123,225,30)
				Blender.Draw.Button("Exit",2,4,70,225,25)

def event(evt,val):  # Define mouse and keyboard press events
        if evt == Blender.Draw.ESCKEY: # Example if esc key pressed
                Blender.Draw.Exit()    # then exit script
                return                 # return from the function

def button(evt):
				if evt == 1:
					
					fname = Blender.Get('filename')
					ln = len( fname )
					name = fname[ :ln - 6 ] + '.bxo'#Blender.Get('filename').strip(".blend") + ".bxo"
					
					#Blender.Window.FileSelector( DoExport, "Export", name )
					DoExport( name )
					#DoExport( basemapstring )
					#Blender.Window.Redraw() # This will redraw the 3d window.
					
				if evt == 2:
					Blender.Draw.Exit()
				
#run gui
Blender.Draw.Register(draw,event,button)


def wrFloat( file, inData ):
	datas = struct.pack('f',inData); #bx object file
	file.write(datas)

def wrInt( file, inData ):
	datas = struct.pack('i',inData); #bx object file
	file.write(datas)

def wr( file, inType, inData ):
	datas = struct.pack(inType,inData); #bx object file
	file.write(datas)


def DoExport( inFileName ):
	
	optApplyObjTrans = 0
	optForceOneFaceGroup = 0
	print( "Exporting: ",inFileName )
	

	scn = bpy.data.scenes.active
	obs = scn.objects
	
	
	#******************************************** WRITE TO FILE *************************************************
	
	mapstring = inFileName
	file = open( mapstring, "wb")
	
	random.seed()
	hash = random.randint( 0, 2 ** 16 )	#I LIED!!  IT'S NOT A REAL HASH! >:D
	
	wr( file, 'i', 34 ) #bx object file
	wr( file, 'i', 1 ) 	#version
	wr( file, 'i', hash )
	
	#------------WRITE OBJECTS
	
	numobj = 0
	curobj = -1
	#for o in Blender.Object.Get():
	
	# used to sort by name
	objList = []
	
	for o in obs:
		if(o.getType() == "Mesh"):
			curobj += 1
			numobj += 1
			objList += [ [ o.getName(), o ] ]
			
	print( "Objects used: ", numobj )
	objList.sort()
	print(  objList )
	wr( file, 'i', numobj )
	
	
	for olist in objList:	
				o = olist[ 1 ]
				ob = o.getData()
				#print dir(ob)
				#print dir(o)
				matrix = o.matrixWorld
				#print "WRITE OBJ"
				#################TODO: output properties.
				
				oname = o.getName()
				print( "Exporting", oname )
				namelen = len(oname)
				if( namelen > 31 ):
					namelen = 31
				wr( file, 'i', namelen )
				
				for i in xrange( namelen ):
					wr( file, 'c', oname[i] )
				
				#output origin!
				wr( file, 'f', matrix[3][0] )
				wr( file, 'f', matrix[3][1] )
				wr( file, 'f', matrix[3][2] )
				
				numverts = len( ob.verts )
				#output number of verts, then verts
				wr( file, 'i', numverts )
				
				#had to do this, since normals should not be affected by the translate coords of getmatrix
				newmatrix = Blender.Mathutils.Matrix(
					(matrix[0][0],matrix[0][1],matrix[0][2]),
					(matrix[1][0],matrix[1][1],matrix[1][2]),
					(matrix[2][0],matrix[2][1],matrix[2][2])
					)
					
				for v in ob.verts:	############################### OUTPUT VERTS
						#write verts
						if( optApplyObjTrans == 0 ):
							wr( file, 'f', (v.co * newmatrix)[0] )
							wr( file, 'f', (v.co * newmatrix)[1] )
							wr( file, 'f', (v.co * newmatrix)[2] )
							
						else:
							wr( file, 'f', (v.co * matrix)[0] )
							wr( file, 'f', (v.co * matrix)[1] )
							wr( file, 'f', (v.co * matrix)[2] )
							
						#write vert normal
						wr( file, 'f', (v.no * newmatrix).normalize()[0] )
						wr( file, 'f', (v.no * newmatrix).normalize()[1] )
						wr( file, 'f', (v.no * newmatrix).normalize()[2] )
						
						#curind += 1
				
				#output number of triangles and quads
				#[faces sep'd by material] (assume 0,1,2,3 for mat index) (assume p.mat == p.materialIndex)
				
				#facegroup count [
				faceCount = [0,0]
				
				for p in ob.faces:
					if( len( p.v ) == 4 ):
						faceCount[1] += 1
					if( len( p.v ) == 3 ):
						faceCount[0] += 1
					
				wr( file, 'i', faceCount[0] )
				wr( file, 'i', faceCount[1] )
				
				curipoly = 0
					
				
				for t in xrange(2):
					triquad = 3+t
					for p in ob.faces:
						if( len( p.v ) == triquad ):
							e = Blender.Mathutils.Vector((p.normal[0]),(p.normal[1]),(p.normal[2]),0)
							if e[0] == 0 and e[1] == 0 and e[2] == 0:
								e[0] = 1
								
							wr( file, 'B', int(p.smooth) )
							wr( file, 'f', (e * newmatrix).normalize()[0] )
							wr( file, 'f', (e * newmatrix).normalize()[1] )
							wr( file, 'f', (e * newmatrix).normalize()[2] )
							
							for cc in range(len(p.v)): #list index, and uv coords below
								wr( file, 'i', p.v[cc].index )
								if ob.hasFaceUV():
									wr( file, 'f', p.uv[cc][0] )
									wr( file, 'f', p.uv[cc][1] )

								else:
									wr( file, 'f', 0 )
									wr( file, 'f', 0 )
							
	file.close()
	Blender.Draw.Register(draw,event,button)
	#Blender.Window.Redraw() # This will redraw the 3d window. 
	
