GLES drivers adapted, but only did make compile-tests. git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@6038 dfc29bdd-3216-0410-991c-e03cc46cb475
		
			
				
	
	
		
			1612 lines
		
	
	
		
			60 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			1612 lines
		
	
	
		
			60 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!BPY
 | |
| 
 | |
| """
 | |
| Name: 'B3D Exporter (.b3d)...'
 | |
| Blender: 259
 | |
| Group: 'Export'
 | |
| Tooltip: 'Export to Blitz3D file format (.b3d)'
 | |
| """
 | |
| __author__ = ["iego 'GaNDaLDF' Parisi, MTLZ (is06), Joerg Henrichs, Marianne Gagnon"]
 | |
| __url__ = ["www.gandaldf.com"]
 | |
| __version__ = "3.0"
 | |
| __bpydoc__ = """\
 | |
| """
 | |
| 
 | |
| # BLITZ3D EXPORTER 3.0
 | |
| # Copyright (C) 2009 by Diego "GaNDaLDF" Parisi  -  www.gandaldf.com
 | |
| # Lightmap issue fixed by Capricorn 76 Pty. Ltd. - www.capricorn76.com
 | |
| # Blender 2.63 compatiblity based on work by MTLZ, www.is06.com
 | |
| # With changes by Marianne Gagnon, Joerg Henrichs and Vincent Lejeune, supertuxkart.sf.net (Copyright (C) 2011-2012)
 | |
| #
 | |
| # LICENSE:
 | |
| # 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.
 | |
| #
 | |
| # You should have received a copy of the GNU General Public License
 | |
| # along with this program; if not, write to the Free Software
 | |
| # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 | |
| 
 | |
| bl_info = {
 | |
|     "name": "B3D (BLITZ3D) Model Exporter",
 | |
|     "description": "Exports a blender scene or object to the B3D (BLITZ3D) format",
 | |
|     "author": "Diego 'GaNDaLDF' Parisi, MTLZ (is06), Joerg Henrichs, Marianne Gagnon, Vincent Lejeune",
 | |
|     "version": (3,1),
 | |
|     "blender": (2, 5, 9),
 | |
|     "api": 31236,
 | |
|     "location": "File > Export",
 | |
|     "warning": '', # used for warning icon and text in addons panel
 | |
|     "wiki_url": "http://supertuxkart.sourceforge.net/Get_involved",
 | |
|     "tracker_url": "https://sourceforge.net/apps/trac/supertuxkart/",
 | |
|     "category": "Import-Export"}
 | |
| 
 | |
| 
 | |
| import bpy
 | |
| import sys,os,os.path,struct,math,string
 | |
| import mathutils
 | |
| import math
 | |
| 
 | |
| if not hasattr(sys,"argv"): sys.argv = ["???"]
 | |
| 
 | |
| 
 | |
| #Global Stacks
 | |
| b3d_parameters = {}
 | |
| texture_flags  = []
 | |
| texs_stack     = {}
 | |
| brus_stack     = []
 | |
| vertex_groups  = []
 | |
| bone_stack     = {}
 | |
| keys_stack     = []
 | |
| 
 | |
| texture_count = 0
 | |
| 
 | |
| # bone_stack indices constants
 | |
| BONE_PARENT_MATRIX = 0
 | |
| BONE_PARENT = 1
 | |
| BONE_ITSELF = 2
 | |
| 
 | |
| # texture stack indices constants
 | |
| TEXTURE_ID = 0
 | |
| TEXTURE_FLAGS = 1
 | |
| 
 | |
| per_face_vertices = {}
 | |
| 
 | |
| the_scene = None
 | |
| 
 | |
| #Transformation Matrix
 | |
| TRANS_MATRIX = mathutils.Matrix([[1,0,0,0],[0,0,1,0],[0,1,0,0],[0,0,0,1]])
 | |
| BONE_TRANS_MATRIX = mathutils.Matrix([[-1,0,0,0],[0,0,-1,0],[0,-1,0,0],[0,0,0,1]])
 | |
| 
 | |
| DEBUG = False
 | |
| PROGRESS = True
 | |
| PROGRESS_VERBOSE = False
 | |
| 
 | |
| tesselated_objects = {}
 | |
| 
 | |
| #Support Functions
 | |
| def write_int(value):
 | |
|     return struct.pack("<i",value)
 | |
| 
 | |
| def write_float(value):
 | |
|     return struct.pack("<f",value)
 | |
| 
 | |
| def write_float_couple(value1, value2):
 | |
|     return struct.pack("<ff", value1, value2)
 | |
| 
 | |
| def write_float_triplet(value1, value2, value3):
 | |
|     return struct.pack("<fff", value1, value2, value3)
 | |
| 
 | |
| def write_float_quad(value1, value2, value3, value4):
 | |
|     return struct.pack("<ffff", value1, value2, value3, value4)
 | |
|     
 | |
| def write_string(value):
 | |
|     encoded = str.encode(value)
 | |
|     if len(encoded) > 48:
 | |
|         value = encoded[0:48]
 | |
|     binary_format = "<%ds"%(len(encoded)+1)
 | |
|     return struct.pack(binary_format, encoded)
 | |
| 
 | |
| def write_chunk(name,value):
 | |
|     dummy = bytearray()
 | |
|     return dummy + name + write_int(len(value)) + value
 | |
| 
 | |
| trimmed_paths = {}
 | |
| 
 | |
| def getArmatureAnimationEnd(armature):
 | |
|     end_frame = 1
 | |
|     if armature.animation_data.action:
 | |
|         ipo = armature.animation_data.action.fcurves
 | |
|         for curve in ipo:
 | |
|             if "pose" in curve.data_path:
 | |
|                 end_frame = max(end_frame, curve.keyframe_points[-1].co[0])
 | |
|     
 | |
|     for nla_track in armature.animation_data.nla_tracks:
 | |
|         if len(nla_track.strips) > 0:
 | |
|             end_frame = max(end_frame, nla_track.strips[-1].frame_end)
 | |
|         
 | |
|     return end_frame
 | |
| 
 | |
| # ==== Write B3D File ====
 | |
| # (main exporter function)
 | |
| def write_b3d_file(filename, objects=[]):
 | |
|     global texture_flags, texs_stack, trimmed_paths, tesselated_objects
 | |
|     global brus_stack, vertex_groups, bone_stack, keys_stack
 | |
| 
 | |
|     #Global Stacks
 | |
|     texture_flags = []
 | |
|     texs_stack = {}
 | |
|     brus_stack = []
 | |
|     vertex_groups = []
 | |
|     bone_stack = []
 | |
|     keys_stack = []
 | |
|     trimmed_paths = {}
 | |
|     file_buf = bytearray()
 | |
|     temp_buf = bytearray()
 | |
|     tesselated_objects = {}
 | |
| 
 | |
|     import time
 | |
|     start = time.time()
 | |
| 
 | |
|     temp_buf += write_int(1) #Version
 | |
|     temp_buf += write_texs(objects) #TEXS
 | |
|     temp_buf += write_brus(objects) #BRUS
 | |
|     temp_buf += write_node(objects) #NODE
 | |
| 
 | |
|     if len(temp_buf) > 0:
 | |
|         file_buf += write_chunk(b"BB3D",temp_buf)
 | |
|         temp_buf = ""
 | |
| 
 | |
|     file = open(filename,'wb')
 | |
|     file.write(file_buf)
 | |
|     file.close()
 | |
|     
 | |
|     # free memory
 | |
|     trimmed_paths = {}
 | |
|     
 | |
|     end = time.time()
 | |
|     
 | |
|     print("Exported in", (end - start))
 | |
| 
 | |
| 
 | |
| def tesselate_if_needed(objdata):
 | |
|     if objdata not in tesselated_objects:
 | |
|         objdata.calc_tessface()
 | |
|         tesselated_objects[objdata] = True
 | |
|     return objdata
 | |
| 
 | |
| def getUVTextures(obj_data):
 | |
|     # BMesh in blender 2.63 broke this
 | |
|     if bpy.app.version[1] >= 63:
 | |
|         return tesselate_if_needed(obj_data).tessface_uv_textures
 | |
|     else:
 | |
|         return obj_data.uv_textures
 | |
| 
 | |
| def getFaces(obj_data):
 | |
|     # BMesh in blender 2.63 broke this
 | |
|     if bpy.app.version[1] >= 63:
 | |
|         return tesselate_if_needed(obj_data).tessfaces
 | |
|     else:
 | |
|         return obj_data.faces
 | |
| 
 | |
| def getVertexColors(obj_data):
 | |
|     # BMesh in blender 2.63 broke this
 | |
|     if bpy.app.version[1] >= 63:
 | |
|         return tesselate_if_needed(obj_data).tessface_vertex_colors
 | |
|     else:
 | |
|         return obj_data.vertex_colors
 | |
| 
 | |
| # ==== Write TEXS Chunk ====
 | |
| def write_texs(objects=[]):
 | |
|     global b3d_parameters
 | |
|     global trimmed_paths
 | |
|     global texture_count
 | |
|     texs_buf = bytearray()
 | |
|     temp_buf = bytearray()
 | |
|     layer_max = 0
 | |
|     obj_count = 0
 | |
|     set_wrote = 0
 | |
| 
 | |
|     if objects:
 | |
|         exp_obj = objects
 | |
|     else:
 | |
|         if b3d_parameters.get("export-selected"):
 | |
|             exp_obj = [ob for ob in bpy.data.objects if ob.select]
 | |
|         else:
 | |
|             exp_obj = bpy.data.objects
 | |
| 
 | |
|     if PROGRESS: print(len(exp_obj),"TEXS")
 | |
| 
 | |
|     if PROGRESS_VERBOSE: progress = 0
 | |
| 
 | |
|     for obj in exp_obj:
 | |
|         
 | |
|         if PROGRESS_VERBOSE:
 | |
|             progress = progress + 1
 | |
|             if (progress % 10 == 0): print("TEXS",progress,"/",len(exp_obj))
 | |
|         
 | |
|         if obj.type == "MESH":
 | |
|             set_count = 0
 | |
|             set_wrote = 0
 | |
|             #data = obj.getData(mesh = True)
 | |
|             data = obj.data
 | |
|             
 | |
|             # FIXME?
 | |
|             #orig_uvlayer = data.activeUVLayer
 | |
|             
 | |
|             layer_set = [[],[],[],[],[],[],[],[]]
 | |
|             
 | |
|             # 8 UV layers are supported
 | |
|             texture_flags.append([None,None,None,None,None,None,None,None])
 | |
| 
 | |
|             #if len(data.getUVLayerNames()) <= 8:
 | |
|             uv_textures = getUVTextures(data)
 | |
|             if len(uv_textures) <= 8:
 | |
|                 if len(uv_textures) > layer_max:
 | |
|                     layer_max = len(uv_textures)
 | |
|             else:
 | |
|                 layer_max = 8
 | |
| 
 | |
|             for face in getFaces(data):
 | |
|                 for iuvlayer,uvlayer in enumerate(uv_textures):
 | |
|                     if iuvlayer < 8:
 | |
|                         
 | |
|                         # FIXME?
 | |
|                         #data.activeUVLayer = uvlayer
 | |
|                         
 | |
|                         #layer_set[iuvlayer].append(face.uv)
 | |
|                         new_data = None
 | |
|                         try:
 | |
|                             new_data = uvlayer.data[face.index].uv
 | |
|                         except:
 | |
|                             pass
 | |
|                         
 | |
|                         layer_set[iuvlayer].append( new_data )
 | |
| 
 | |
|             for i in range(len(uv_textures)):
 | |
|                 if set_wrote:
 | |
|                     set_count += 1
 | |
|                     set_wrote = 0
 | |
| 
 | |
|                 for iuvlayer in range(i,len(uv_textures)):
 | |
|                     if layer_set[i] == layer_set[iuvlayer]:
 | |
|                         if texture_flags[obj_count][iuvlayer] is None:
 | |
|                             if set_count == 0:
 | |
|                                 tex_flag = 1
 | |
|                             elif set_count == 1:
 | |
|                                 tex_flag = 65536
 | |
|                             elif set_count > 1:
 | |
|                                 tex_flag = 1
 | |
|                             if b3d_parameters.get("mipmap"):
 | |
|                                 enable_mipmaps=8
 | |
|                             else:
 | |
|                                 enable_mipmaps=0
 | |
|                             texture_flags[obj_count][iuvlayer] = tex_flag | enable_mipmaps
 | |
|                             set_wrote = 1
 | |
| 
 | |
|             for face in getFaces(data):
 | |
|                 for iuvlayer,uvlayer in enumerate(uv_textures):
 | |
|                     if iuvlayer < 8:
 | |
|                         
 | |
|                         if not (iuvlayer < len(uv_textures)):
 | |
|                             continue
 | |
|                         
 | |
|                         # FIXME?
 | |
|                         #data.activeUVLayer = uvlayer
 | |
|                         
 | |
|                         #if DEBUG: print("<uv face=", face.index, ">")
 | |
|                         
 | |
|                         img = getUVTextures(data)[iuvlayer].data[face.index].image
 | |
|                         
 | |
|                         if img:
 | |
|                             
 | |
|                             if img.filepath in trimmed_paths:
 | |
|                                 img_name = trimmed_paths[img.filepath]
 | |
|                             else:
 | |
|                                 img_name = bpy.path.basename(img.filepath)
 | |
|                                 trimmed_paths[img.filepath] = img_name
 | |
| 
 | |
|                             if not img_name in texs_stack:
 | |
|                                 texs_stack[img_name] = [len(texs_stack), texture_flags[obj_count][iuvlayer]]
 | |
|                                 temp_buf += write_string(img_name) #Texture File Name
 | |
|                                 temp_buf += write_int(texture_flags[obj_count][iuvlayer]) #Flags
 | |
|                                 temp_buf += write_int(2)   #Blend
 | |
|                                 temp_buf += write_float(0) #X_Pos
 | |
|                                 temp_buf += write_float(0) #Y_Pos
 | |
|                                 temp_buf += write_float(1) #X_Scale
 | |
|                                 temp_buf += write_float(1) #Y_Scale
 | |
|                                 temp_buf += write_float(0) #Rotation
 | |
|                             #else:
 | |
|                             #    if DEBUG: print("    <image id=(previous)","name=","'"+img_name+"'","/>")
 | |
|                             
 | |
|                         #if DEBUG: print("</uv>")
 | |
| 
 | |
|             obj_count += 1
 | |
| 
 | |
|             #FIXME?
 | |
|             #if orig_uvlayer:
 | |
|             #    data.activeUVLayer = orig_uvlayer
 | |
| 
 | |
|     texture_count = layer_max
 | |
| 
 | |
|     if len(temp_buf) > 0:
 | |
|         texs_buf += write_chunk(b"TEXS",temp_buf)
 | |
|         temp_buf = ""
 | |
| 
 | |
|     return texs_buf
 | |
| 
 | |
| # ==== Write BRUS Chunk ====
 | |
| def write_brus(objects=[]):
 | |
|     global b3d_parameters
 | |
|     global trimmed_paths
 | |
|     global texture_count
 | |
|     brus_buf = bytearray()
 | |
|     temp_buf = bytearray()
 | |
|     mat_count = 0
 | |
|     obj_count = 0
 | |
| 
 | |
|     if DEBUG: print("<!-- BRUS chunk -->")
 | |
| 
 | |
|     if objects:
 | |
|         exp_obj = objects
 | |
|     else:
 | |
|         if  b3d_parameters.get("export-selected"):
 | |
|             exp_obj = [ob for ob in bpy.data.objects if ob.select]
 | |
|         else:
 | |
|             exp_obj = bpy.data.objects
 | |
| 
 | |
|     if PROGRESS: print(len(exp_obj),"BRUS")
 | |
|     if PROGRESS_VERBOSE: progress = 0
 | |
| 
 | |
|     for obj in exp_obj:
 | |
|         
 | |
|         if PROGRESS_VERBOSE:
 | |
|             progress += 1
 | |
|             if (progress % 10 == 0): print("BRUS",progress,"/",len(exp_obj))
 | |
|             
 | |
|         if obj.type == "MESH":
 | |
|             data = obj.data
 | |
|             
 | |
|             uv_textures = getUVTextures(data)
 | |
|             
 | |
|             if len(uv_textures) <= 0:
 | |
|                 continue
 | |
| 
 | |
|             if DEBUG: print("<obj name=",obj.name,">")
 | |
| 
 | |
|             img_found = 0
 | |
|             
 | |
|             for face in getFaces(data):
 | |
|                 
 | |
|                 face_stack = []
 | |
|                 
 | |
|                 for iuvlayer,uvlayer in enumerate(uv_textures):
 | |
|                     if iuvlayer < 8:
 | |
|                         
 | |
|                         img_id = -1
 | |
|                         
 | |
|                         if face.index >= len(uv_textures[iuvlayer].data):
 | |
|                             continue
 | |
|                         
 | |
|                         img = uv_textures[iuvlayer].data[face.index].image
 | |
|                         
 | |
|                         if not img:
 | |
|                             continue
 | |
|                         
 | |
|                         img_found = 1
 | |
|                         
 | |
|                         if img.filepath in trimmed_paths:
 | |
|                             img_name = trimmed_paths[img.filepath]
 | |
|                         else:
 | |
|                             img_name = os.path.basename(img.filepath)
 | |
|                             trimmed_paths[img.filepath] = img_name
 | |
|                         
 | |
|                         if DEBUG: print("    <!-- Building FACE 'stack' -->")
 | |
|                         
 | |
|                         if img_name in texs_stack:
 | |
|                             img_id = texs_stack[img_name][TEXTURE_ID]
 | |
|                         
 | |
|                         face_stack.insert(iuvlayer,img_id)
 | |
|                         if DEBUG: print("    <uv face=",face.index,"layer=", iuvlayer, " imgid=", img_id, "/>")
 | |
| 
 | |
|                 for i in range(len(face_stack),texture_count):
 | |
|                     face_stack.append(-1)
 | |
| 
 | |
| 
 | |
|                 if DEBUG: print("    <!-- Writing chunk -->")
 | |
|                 
 | |
|                 if not img_found:
 | |
|                     if data.materials:
 | |
|                         if data.materials[face.material_index]:
 | |
|                             mat_data = data.materials[face.material_index]
 | |
|                             mat_colr = mat_data.diffuse_color[0]
 | |
|                             mat_colg = mat_data.diffuse_color[1]
 | |
|                             mat_colb = mat_data.diffuse_color[2]
 | |
|                             mat_alpha = mat_data.alpha
 | |
|                             mat_name = mat_data.name
 | |
| 
 | |
|                             if not mat_name in brus_stack:
 | |
|                                 brus_stack.append(mat_name)
 | |
|                                 temp_buf += write_string(mat_name) #Brush Name
 | |
|                                 temp_buf += write_float(mat_colr)  #Red
 | |
|                                 temp_buf += write_float(mat_colg)  #Green
 | |
|                                 temp_buf += write_float(mat_colb)  #Blue
 | |
|                                 temp_buf += write_float(mat_alpha) #Alpha
 | |
|                                 temp_buf += write_float(0)         #Shininess
 | |
|                                 temp_buf += write_int(1)           #Blend
 | |
|                                 if b3d_parameters.get("vertex-colors") and len(getVertexColors(data)):
 | |
|                                     temp_buf += write_int(2) #Fx
 | |
|                                 else:
 | |
|                                     temp_buf += write_int(0) #Fx
 | |
| 
 | |
|                                 for i in face_stack:
 | |
|                                     temp_buf += write_int(i) #Texture ID
 | |
|                     else:
 | |
|                         if b3d_parameters.get("vertex-colors") and len(getVertexColors(data)) > 0:
 | |
|                             if not face_stack in brus_stack:
 | |
|                                 brus_stack.append(face_stack)
 | |
|                                 mat_count += 1
 | |
|                                 temp_buf += write_string("Brush.%.3i"%mat_count) #Brush Name
 | |
|                                 temp_buf += write_float(1) #Red
 | |
|                                 temp_buf += write_float(1) #Green
 | |
|                                 temp_buf += write_float(1) #Blue
 | |
|                                 temp_buf += write_float(1) #Alpha
 | |
|                                 temp_buf += write_float(0) #Shininess
 | |
|                                 temp_buf += write_int(1)   #Blend
 | |
|                                 temp_buf += write_int(2)   #Fx
 | |
| 
 | |
|                                 for i in face_stack:
 | |
|                                     temp_buf += write_int(i) #Texture ID
 | |
|                 else: # img_found
 | |
|                 
 | |
|                     if not face_stack in brus_stack:
 | |
|                         brus_stack.append(face_stack)
 | |
|                         mat_count += 1
 | |
|                         temp_buf += write_string("Brush.%.3i"%mat_count) #Brush Name
 | |
|                         temp_buf += write_float(1) #Red
 | |
|                         temp_buf += write_float(1) #Green
 | |
|                         temp_buf += write_float(1) #Blue
 | |
|                         temp_buf += write_float(1) #Alpha
 | |
|                         temp_buf += write_float(0) #Shininess
 | |
|                         temp_buf += write_int(1)   #Blend
 | |
|                         
 | |
|                         if DEBUG: print("    <brush id=",len(brus_stack),">")
 | |
|                         
 | |
|                         if b3d_parameters.get("vertex-colors") and len(getVertexColors(data)) > 0:
 | |
|                             temp_buf += write_int(2) #Fx
 | |
|                         else:
 | |
|                             temp_buf += write_int(0) #Fx
 | |
| 
 | |
|                         for i in face_stack:
 | |
|                             temp_buf += write_int(i) #Texture ID
 | |
|                             if DEBUG: print("        <texture id=",i,">")
 | |
|                         
 | |
|                         if DEBUG: print("    </brush>")
 | |
|                 
 | |
|                 if DEBUG: print("")
 | |
| 
 | |
|             if DEBUG: print("</obj>")
 | |
|             obj_count += 1
 | |
| 
 | |
|             #FIXME?
 | |
|             #if orig_uvlayer:
 | |
|             #    data.activeUVLayer = orig_uvlayer
 | |
| 
 | |
|     if len(temp_buf) > 0:
 | |
|         brus_buf += write_chunk(b"BRUS",write_int(texture_count) + temp_buf) #N Texs
 | |
|         temp_buf = ""
 | |
|     
 | |
|     return brus_buf
 | |
| 
 | |
| # ==== Write NODE Chunk ====
 | |
| def write_node(objects=[]):
 | |
|     global bone_stack
 | |
|     global keys_stack
 | |
|     global b3d_parameters
 | |
|     global the_scene
 | |
|     
 | |
|     root_buf = []
 | |
|     node_buf = []
 | |
|     main_buf = bytearray()
 | |
|     temp_buf = []
 | |
|     obj_count = 0
 | |
|     amb_light = 0
 | |
| 
 | |
|     num_mesh = 0
 | |
|     num_ligs = 0
 | |
|     num_cams = 0
 | |
|     num_lorc = 0
 | |
|     #exp_scn = Blender.Scene.GetCurrent()
 | |
|     #exp_scn = the_scene
 | |
|     #exp_con = exp_scn.getRenderingContext()
 | |
| 
 | |
|     #first_frame = Blender.Draw.Create(exp_con.startFrame())
 | |
|     #last_frame = Blender.Draw.Create(exp_con.endFrame())
 | |
|     #num_frames = last_frame.val - first_frame.val
 | |
|     first_frame = the_scene.frame_start
 | |
| 
 | |
|     if DEBUG: print("<node first_frame=", first_frame, ">")
 | |
| 
 | |
|     if objects:
 | |
|         exp_obj = objects
 | |
|     else:
 | |
|         if b3d_parameters.get("export-selected"):
 | |
|             exp_obj = [ob for ob in bpy.data.objects if ob.select]
 | |
|         else:
 | |
|             exp_obj = bpy.data.objects
 | |
| 
 | |
|     for obj in exp_obj:
 | |
|         if obj.type == "MESH":
 | |
|             num_mesh += 1
 | |
|         if obj.type == "CAMERA":
 | |
|             num_cams += 1
 | |
|         if obj.type == "LAMP":
 | |
|             num_ligs += 1
 | |
| 
 | |
|     if b3d_parameters.get("cameras"):
 | |
|         num_lorc += num_cams
 | |
| 
 | |
|     if b3d_parameters.get("lights"):
 | |
|         num_lorc += 1
 | |
|         num_lorc += num_ligs
 | |
| 
 | |
|     if num_mesh + num_lorc > 1:
 | |
|         exp_root = 1
 | |
|     else:
 | |
|         exp_root = 0
 | |
| 
 | |
|     if exp_root:
 | |
|         root_buf.append(write_string("ROOT")) #Node Name
 | |
| 
 | |
|         root_buf.append(write_float_triplet(0, 0, 0)) #Position X,Y,Z
 | |
|         root_buf.append(write_float_triplet(1, 1, 1)) #Scale X, Y, Z
 | |
|         root_buf.append(write_float_quad(1, 0, 0, 0)) #Rotation W, X, Y, Z
 | |
| 
 | |
|     if PROGRESS: progress = 0
 | |
| 
 | |
|     for obj in exp_obj:
 | |
|         
 | |
|         if PROGRESS:
 | |
|             progress += 1
 | |
|             print("NODE:",progress,"/",len(exp_obj),obj.name)
 | |
|         
 | |
|         if obj.type == "MESH":
 | |
|             
 | |
|             if DEBUG: print("    <mesh name=",obj.name,">")
 | |
|             
 | |
|             bone_stack = {}
 | |
|             keys_stack = []
 | |
| 
 | |
|             anim_data = None
 | |
|             
 | |
|             # check if this object has an armature modifier
 | |
|             for curr_mod in obj.modifiers:
 | |
|                 if curr_mod.type == 'ARMATURE':
 | |
|                     arm = curr_mod.object
 | |
|                     if arm is not None:
 | |
|                         anim_data = arm.animation_data
 | |
| 
 | |
|             # check if this object has an armature parent (second way to do armature animations in blender)
 | |
|             if anim_data is None:
 | |
|                 if obj.parent:
 | |
|                     if obj.parent.type == "ARMATURE":
 | |
|                         arm = obj.parent
 | |
|                         if arm.animation_data:
 | |
|                             anim_data = arm.animation_data
 | |
| 
 | |
|             if anim_data:
 | |
|                 matrix = mathutils.Matrix()
 | |
| 
 | |
|                 temp_buf.append(write_string(obj.name)) #Node Name
 | |
|                 
 | |
|                 position = matrix.to_translation()
 | |
|                 temp_buf.append(write_float_triplet(position[0], position[1], position[2])) #Position X, Y, Z
 | |
| 
 | |
|                 scale = matrix.to_scale()
 | |
|                 temp_buf.append(write_float_triplet(scale[0], scale[2], scale[1])) #Scale X, Y, Z
 | |
| 
 | |
|                 if DEBUG: print("        <arm name=", obj.name, " loc=", -position[0], position[1], position[2], " scale=", scale[0], scale[1], scale[2], "/>")
 | |
|                 
 | |
|                 quat = matrix.to_quaternion()
 | |
|                 quat.normalize()
 | |
| 
 | |
|                 temp_buf.append(write_float_quad(quat.w, quat.x, quat.z, quat.y))
 | |
|             else:
 | |
|                 if b3d_parameters.get("local-space"):
 | |
|                     matrix = TRANS_MATRIX.copy()
 | |
|                     scale_matrix = mathutils.Matrix()
 | |
|                 else:
 | |
|                     matrix = obj.matrix_world*TRANS_MATRIX
 | |
|                     scale_matrix = obj.matrix_world.copy()
 | |
|                 
 | |
|                 
 | |
|                 if bpy.app.version[1] >= 62:
 | |
|                     # blender 2.62 broke the API : Column-major access was changed to row-major access
 | |
|                     tmp = mathutils.Vector([matrix[0][1], matrix[1][1], matrix[2][1], matrix[3][1]])
 | |
|                     matrix[0][1] = matrix[0][2]
 | |
|                     matrix[1][1] = matrix[1][2]
 | |
|                     matrix[2][1] = matrix[2][2]
 | |
|                     matrix[3][1] = matrix[3][2]
 | |
|                     
 | |
|                     matrix[0][2] = tmp[0]
 | |
|                     matrix[1][2] = tmp[1]
 | |
|                     matrix[2][2] = tmp[2]
 | |
|                     matrix[3][2] = tmp[3]
 | |
|                 else:
 | |
|                     tmp = mathutils.Vector(matrix[1])
 | |
|                     matrix[1] = matrix[2]
 | |
|                     matrix[2] = tmp
 | |
| 
 | |
|                 temp_buf.append(write_string(obj.name)) #Node Name
 | |
| 
 | |
|                 #print("Matrix : ", matrix)
 | |
|                 position = matrix.to_translation()
 | |
| 
 | |
|                 temp_buf.append(write_float_triplet(position[0], position[2], position[1])) 
 | |
| 
 | |
|                 scale = scale_matrix.to_scale()
 | |
|                 temp_buf.append(write_float_triplet(scale[0], scale[2], scale[1]))
 | |
| 
 | |
|                 quat = matrix.to_quaternion()
 | |
|                 quat.normalize()
 | |
| 
 | |
|                 temp_buf.append(write_float_quad(quat.w, quat.x, quat.z, quat.y))
 | |
|                   
 | |
|                 if DEBUG:
 | |
|                     print("        <position>",position[0],position[2],position[1],"</position>")
 | |
|                     print("        <scale>",scale[0],scale[1],scale[2],"</scale>")
 | |
|                     print("        <rotation>", quat.w, quat.x, quat.y, quat.z, "</rotation>")
 | |
|             
 | |
|             if anim_data:
 | |
|                 the_scene.frame_set(1,subframe=0.0)
 | |
|                 
 | |
|                 arm_matrix = arm.matrix_world
 | |
|                 
 | |
|                 if b3d_parameters.get("local-space"):
 | |
|                     arm_matrix = mathutils.Matrix()
 | |
|                 
 | |
|                 def read_armature(arm_matrix,bone,parent = None):
 | |
|                     if (parent and not bone.parent.name == parent.name):
 | |
|                         return
 | |
| 
 | |
|                     matrix = mathutils.Matrix(bone.matrix)
 | |
|                     
 | |
|                     if parent:
 | |
| 
 | |
|                         #print("==== "+bone.name+" ====")
 | |
|                         a = (bone.matrix_local)
 | |
|                         
 | |
|                         #print("A : [%.2f %.2f %.2f %.2f]" % (a[0][0], a[0][1], a[0][2], a[0][3]))
 | |
|                         #print("    [%.2f %.2f %.2f %.2f]" % (a[1][0], a[1][1], a[1][2], a[1][3]))
 | |
|                         #print("    [%.2f %.2f %.2f %.2f]" % (a[2][0], a[2][1], a[2][2], a[2][3]))
 | |
|                         #print("    [%.2f %.2f %.2f %.2f]" % (a[3][0], a[3][1], a[3][2], a[3][3]))
 | |
|                         
 | |
|                         b = (parent.matrix_local.inverted().to_4x4())
 | |
|                         
 | |
|                         #print("B : [%.2f %.2f %.2f %.2f]" % (b[0][0], b[0][1], b[0][2], b[0][3]))
 | |
|                         #print("    [%.2f %.2f %.2f %.2f]" % (b[1][0], b[1][1], b[1][2], b[1][3]))
 | |
|                         #print("    [%.2f %.2f %.2f %.2f]" % (b[2][0], b[2][1], b[2][2], b[2][3]))
 | |
|                         #print("    [%.2f %.2f %.2f %.2f]" % (b[3][0], b[3][1], b[3][2], b[3][3]))
 | |
|                         
 | |
|                         par_matrix = b * a
 | |
|                         
 | |
|                         transform = mathutils.Matrix([[1,0,0,0],[0,0,-1,0],[0,-1,0,0],[0,0,0,1]])
 | |
|                         par_matrix = transform*par_matrix*transform
 | |
|                         
 | |
|                         # FIXME: that's ugly, find a clean way to change the matrix.....
 | |
|                         if bpy.app.version[1] >= 62:
 | |
|                             # blender 2.62 broke the API : Column-major access was changed to row-major access
 | |
|                             # TODO: test me
 | |
|                             par_matrix[1][3] = -par_matrix[1][3]
 | |
|                             par_matrix[2][3] = -par_matrix[2][3]
 | |
|                         else:
 | |
|                             par_matrix[3][1] = -par_matrix[3][1]
 | |
|                             par_matrix[3][2] = -par_matrix[3][2]
 | |
|                         
 | |
|                         #c = par_matrix
 | |
|                         #print("With parent")
 | |
|                         #print("C : [%.3f %.3f %.3f %.3f]" % (c[0][0], c[0][1], c[0][2], c[0][3]))
 | |
|                         #print("    [%.3f %.3f %.3f %.3f]" % (c[1][0], c[1][1], c[1][2], c[1][3]))
 | |
|                         #print("    [%.3f %.3f %.3f %.3f]" % (c[2][0], c[2][1], c[2][2], c[2][3]))
 | |
|                         #print("    [%.3f %.3f %.3f %.3f]" % (c[3][0], c[3][1], c[3][2], c[3][3]))
 | |
|                         
 | |
|                     else:
 | |
|                         
 | |
|                         #print("==== "+bone.name+" ====")
 | |
|                         #print("Without parent")
 | |
| 
 | |
|                         m = arm_matrix*bone.matrix_local
 | |
|                         
 | |
|                         #c = arm.matrix_world
 | |
|                         #print("A : [%.3f %.3f %.3f %.3f]" % (c[0][0], c[0][1], c[0][2], c[0][3]))
 | |
|                         #print("    [%.3f %.3f %.3f %.3f]" % (c[1][0], c[1][1], c[1][2], c[1][3]))
 | |
|                         #print("    [%.3f %.3f %.3f %.3f]" % (c[2][0], c[2][1], c[2][2], c[2][3]))
 | |
|                         #print("    [%.3f %.3f %.3f %.3f]" % (c[3][0], c[3][1], c[3][2], c[3][3]))
 | |
|                         
 | |
|                         #c = bone.matrix_local
 | |
|                         #print("B : [%.3f %.3f %.3f %.3f]" % (c[0][0], c[0][1], c[0][2], c[0][3]))
 | |
|                         #print("    [%.3f %.3f %.3f %.3f]" % (c[1][0], c[1][1], c[1][2], c[1][3]))
 | |
|                         #print("    [%.3f %.3f %.3f %.3f]" % (c[2][0], c[2][1], c[2][2], c[2][3]))
 | |
|                         #print("    [%.3f %.3f %.3f %.3f]" % (c[3][0], c[3][1], c[3][2], c[3][3]))
 | |
|                         
 | |
|                         par_matrix = m*mathutils.Matrix([[-1,0,0,0],[0,0,1,0],[0,1,0,0],[0,0,0,1]])
 | |
|                                                 
 | |
|                         #c = par_matrix
 | |
|                         #print("C : [%.3f %.3f %.3f %.3f]" % (c[0][0], c[0][1], c[0][2], c[0][3]))
 | |
|                         #print("    [%.3f %.3f %.3f %.3f]" % (c[1][0], c[1][1], c[1][2], c[1][3]))
 | |
|                         #print("    [%.3f %.3f %.3f %.3f]" % (c[2][0], c[2][1], c[2][2], c[2][3]))
 | |
|                         #print("    [%.3f %.3f %.3f %.3f]" % (c[3][0], c[3][1], c[3][2], c[3][3]))
 | |
|                         
 | |
| 
 | |
|                     bone_stack[bone.name] = [par_matrix,parent,bone]
 | |
| 
 | |
|                     if bone.children:
 | |
|                         for child in bone.children: read_armature(arm_matrix,child,bone)
 | |
| 
 | |
|                 for bone in arm.data.bones.values():
 | |
|                     if not bone.parent:
 | |
|                         read_armature(arm_matrix,bone)
 | |
| 
 | |
|                 frame_count = first_frame
 | |
|                 
 | |
|                 last_frame = int(getArmatureAnimationEnd(arm))
 | |
|                 num_frames = last_frame - first_frame
 | |
| 
 | |
|                 while frame_count <= last_frame:
 | |
| 
 | |
|                     the_scene.frame_set(int(frame_count), subframe=0.0)
 | |
|                     
 | |
|                     if DEBUG: print("        <frame id=", int(frame_count), ">")
 | |
|                     arm_pose = arm.pose
 | |
|                     arm_matrix = arm.matrix_world
 | |
|                     
 | |
|                     transform = mathutils.Matrix([[-1,0,0,0],[0,0,1,0],[0,1,0,0],[0,0,0,1]])
 | |
|                     arm_matrix = transform*arm_matrix
 | |
|                     #arm_quat = arm_matrix.to_quaternion()
 | |
|                     #arm_quat.normalize()
 | |
| 
 | |
|                     for bone_name in arm.data.bones.keys():
 | |
|                         #bone_matrix = mathutils.Matrix(arm_pose.bones[bone_name].poseMatrix)
 | |
|                         bone_matrix = mathutils.Matrix(arm_pose.bones[bone_name].matrix)
 | |
|                         
 | |
|                         #print("(outer loop) bone_matrix for",bone_name,"=", bone_matrix)
 | |
|                         
 | |
|                         #print(bone_name,":",bone_matrix)
 | |
|                         
 | |
|                         #bone_matrix = bpy.data.scenes[0].objects[0].pose.bones['Bone'].matrix
 | |
|                         
 | |
|                         for ibone in bone_stack:
 | |
|                             
 | |
|                             bone = bone_stack[ibone]
 | |
|                             
 | |
|                             if bone[BONE_ITSELF].name == bone_name:
 | |
|                                 
 | |
|                                 if DEBUG: print("            <bone id=",ibone,"name=",bone_name,">")
 | |
|                                 
 | |
|                                 # == 2.4 exporter ==
 | |
|                                 #if bone_stack[ibone][1]:
 | |
|                                 #    par_matrix = Blender.Mathutils.Matrix(arm_pose.bones[bone_stack[ibone][1].name].poseMatrix)
 | |
|                                 #    bone_matrix *= par_matrix.invert()
 | |
|                                 #else:
 | |
|                                 #    if b3d_parameters.get("local-space"):
 | |
|                                 #        bone_matrix *= TRANS_MATRIX
 | |
|                                 #    else:
 | |
|                                 #        bone_matrix *= arm_matrix
 | |
|                                 #bone_loc = bone_matrix.translationPart()
 | |
|                                 #bone_rot = bone_matrix.rotationPart().toQuat()
 | |
|                                 #bone_rot.normalize()
 | |
|                                 #bone_sca = bone_matrix.scalePart()
 | |
|                                 #keys_stack.append([frame_count - first_frame.val+1,bone_name,bone_loc,bone_sca,bone_rot])
 | |
|                                 
 | |
|                                 # if has parent
 | |
|                                 if bone[BONE_PARENT]:
 | |
|                                     par_matrix = mathutils.Matrix(arm_pose.bones[bone[BONE_PARENT].name].matrix)
 | |
|                                     bone_matrix = par_matrix.inverted()*bone_matrix
 | |
|                                 else:
 | |
|                                     if b3d_parameters.get("local-space"):
 | |
|                                         bone_matrix = bone_matrix*mathutils.Matrix([[-1,0,0,0],[0,0,1,0],[0,1,0,0],[0,0,0,1]])
 | |
|                                     else:
 | |
|                                         
 | |
|                                         #if frame_count == 1:
 | |
|                                         #    print("====",bone_name,"====")
 | |
|                                         #    print("arm_matrix = ", arm_matrix)
 | |
|                                         #    print("bone_matrix = ", bone_matrix)
 | |
|                                         
 | |
|                                         bone_matrix = arm_matrix*bone_matrix
 | |
|                                         
 | |
|                                         #if frame_count == 1:
 | |
|                                         #    print("arm_matrix*bone_matrix", bone_matrix)
 | |
|                                         
 | |
|                                 
 | |
|                                 #print("bone_matrix =", bone_matrix)
 | |
|                                 
 | |
|                                 bone_sca = bone_matrix.to_scale()
 | |
|                                 bone_loc = bone_matrix.to_translation()
 | |
|                                 
 | |
|                                 # FIXME: silly tweaks to resemble the Blender 2.4 exporter output
 | |
|                                 if b3d_parameters.get("local-space"):
 | |
|                                     
 | |
|                                     bone_rot = bone_matrix.to_quaternion()
 | |
|                                     bone_rot.normalize()
 | |
|                                     
 | |
|                                     
 | |
|                                     if not bone[BONE_PARENT]:
 | |
|                                         tmp = bone_rot.z
 | |
|                                         bone_rot.z = bone_rot.y
 | |
|                                         bone_rot.y = tmp
 | |
|                                         
 | |
|                                         bone_rot.x = -bone_rot.x
 | |
|                                     else:
 | |
|                                         tmp = bone_loc.z
 | |
|                                         bone_loc.z = bone_loc.y
 | |
|                                         bone_loc.y = tmp
 | |
| 
 | |
|                                 else:
 | |
|                                     bone_rot = bone_matrix.to_quaternion()
 | |
|                                     bone_rot.normalize()
 | |
| 
 | |
|                                 # Sometimes to_quaternion exhibits precision issue with parent bone
 | |
|                                 # Use quaternion product instead of getting quaternion from the product.
 | |
|                                 #if not bone[BONE_PARENT]:
 | |
|                                 #     bone_rot =  arm_pose.bones[bone_name].matrix.to_quaternion() *  arm_quat
 | |
|                                 #     bone_rot.x = -bone_rot.x
 | |
|                                 #     tmp = bone_rot.z
 | |
|                                 #     bone_rot.z = bone_rot.y
 | |
|                                 #     bone_rot.y = tmp
 | |
| 
 | |
|                                 keys_stack.append([frame_count - first_frame+1, bone_name, bone_loc, bone_sca, bone_rot])
 | |
|                                 if DEBUG: print("                <loc>", bone_loc, "</loc>")
 | |
|                                 if DEBUG: print("                <rot>", bone_rot, "</rot>")
 | |
|                                 if DEBUG: print("                <scale>", bone_sca, "</scale>")
 | |
|                                 if DEBUG: print("            </bone>")
 | |
| 
 | |
|                     frame_count += 1
 | |
| 
 | |
|                     if DEBUG: print("        </frame>")
 | |
| 
 | |
|                 #Blender.Set("curframe",0)
 | |
|                 #Blender.Window.Redraw()
 | |
| 
 | |
|             temp_buf.append(write_node_mesh(obj,obj_count,anim_data,exp_root)) #NODE MESH
 | |
|             
 | |
|             if anim_data:
 | |
|                 temp_buf.append(write_node_anim(num_frames)) #NODE ANIM
 | |
| 
 | |
|                 for ibone in bone_stack:
 | |
|                     if not bone_stack[ibone][BONE_PARENT]:
 | |
|                         temp_buf.append(write_node_node(ibone)) #NODE NODE
 | |
| 
 | |
|             obj_count += 1
 | |
| 
 | |
|             if len(temp_buf) > 0:
 | |
|                 node_buf.append(write_chunk(b"NODE",b"".join(temp_buf)))
 | |
|                 temp_buf = []
 | |
|             
 | |
|             if DEBUG: print("    </mesh>")
 | |
| 
 | |
|         if b3d_parameters.get("cameras"):
 | |
|             if obj.type == "CAMERA":
 | |
|                 data = obj.data
 | |
|                 matrix = obj.getMatrix("worldspace")
 | |
|                 matrix *= TRANS_MATRIX
 | |
| 
 | |
|                 if data.type == "ORTHO":
 | |
|                     cam_type = 2
 | |
|                     cam_zoom = round(data.scale,4)
 | |
|                 else:
 | |
|                     cam_type = 1
 | |
|                     cam_zoom = round(data.lens,4)
 | |
| 
 | |
|                 cam_near = round(data.clipStart,4)
 | |
|                 cam_far = round(data.clipEnd,4)
 | |
| 
 | |
|                 node_name = ("CAMS"+"\n%s"%obj.name+"\n%s"%cam_type+\
 | |
|                              "\n%s"%cam_zoom+"\n%s"%cam_near+"\n%s"%cam_far)
 | |
|                 temp_buf.append(write_string(node_name)) #Node Name
 | |
| 
 | |
|                 position = matrix.translation_part()
 | |
|                 temp_buf.append(write_float_triplet(-position[0], position[1], position[2]))
 | |
| 
 | |
|                 scale = matrix.scale_part()
 | |
|                 temp_buf.append(write_float_triplet(scale[0], scale[1], scale[2]))
 | |
| 
 | |
|                 matrix *= mathutils.Matrix.Rotation(180,4,'Y')
 | |
|                 quat = matrix.to_quat()
 | |
|                 quat.normalize()
 | |
| 
 | |
|                 temp_buf.append(write_float_quad(quat.w, quat.x, quat.y, -quat.z))
 | |
| 
 | |
|                 if len(temp_buf) > 0:
 | |
|                     node_buf.append(write_chunk(b"NODE",b"".join(temp_buf)))
 | |
|                     temp_buf = []
 | |
| 
 | |
|         if b3d_parameters.get("lights"):
 | |
|             if amb_light == 0:
 | |
|                 data = Blender.World.GetCurrent()
 | |
| 
 | |
|                 amb_light = 1
 | |
|                 amb_color = (int(data.amb[2]*255) |(int(data.amb[1]*255) << 8) | (int(data.amb[0]*255) << 16))
 | |
| 
 | |
|                 node_name = (b"AMBI"+"\n%s"%amb_color)
 | |
|                 temp_buf.append(write_string(node_name)) #Node Name
 | |
| 
 | |
|                 temp_buf.append(write_float_triplet(0, 0, 0)) #Position X, Y, Z
 | |
|                 temp_buf.append(write_float_triplet(1, 1, 1)) #Scale X, Y, Z
 | |
|                 temp_buf.append(write_float_quad(1, 0, 0, 0)) #Rotation W, X, Y, Z
 | |
| 
 | |
|                 if len(temp_buf) > 0:
 | |
|                     node_buf.append(write_chunk(b"NODE",b"".join(temp_buf)))
 | |
|                     temp_buf = []
 | |
| 
 | |
|             if obj.type == "LAMP":
 | |
|                 data = obj.getData()
 | |
|                 matrix = obj.getMatrix("worldspace")
 | |
|                 matrix *= TRANS_MATRIX
 | |
| 
 | |
|                 if data.type == 0:
 | |
|                     lig_type = 2
 | |
|                 elif data.type == 2:
 | |
|                     lig_type = 3
 | |
|                 else:
 | |
|                     lig_type = 1
 | |
| 
 | |
|                 lig_angle = round(data.spotSize,4)
 | |
|                 lig_color = (int(data.b*255) |(int(data.g*255) << 8) | (int(data.r*255) << 16))
 | |
|                 lig_range = round(data.dist,4)
 | |
| 
 | |
|                 node_name = ("LIGS"+"\n%s"%obj.name+"\n%s"%lig_type+\
 | |
|                              "\n%s"%lig_angle+"\n%s"%lig_color+"\n%s"%lig_range)
 | |
|                 temp_buf.append(write_string(node_name)) #Node Name
 | |
| 
 | |
|                 position = matrix.translation_part()
 | |
|                 temp_buf.append(write_float_triplet(-position[0], position[1], position[2]))
 | |
|                 if DEBUG: print("        <position>",-position[0],position[1],position[2],"</position>")
 | |
| 
 | |
|                 scale = matrix.scale_part()
 | |
|                 temp_buf.append(write_float_triplet(scale[0], scale[1], scale[2]))
 | |
|                 
 | |
|                 if DEBUG: print("        <scale>",scale[0],scale[1],scale[2],"</scale>")
 | |
| 
 | |
|                 matrix *= mathutils.Matrix.Rotation(180,4,'Y')
 | |
|                 quat = matrix.toQuat()
 | |
|                 quat.normalize()
 | |
| 
 | |
|                 temp_buf.append(write_float_quad(quat.w, quat.x, quat.y, -quat.z))
 | |
|                 if DEBUG: print("        <rotation>", quat.w, quat.x, quat.y, quat.z, "</rotation>")
 | |
| 
 | |
|                 if len(temp_buf) > 0:
 | |
|                     node_buf.append(write_chunk(b"NODE","b".join(temp_buf)))
 | |
|                     temp_buf = []
 | |
|     
 | |
|     if len(node_buf) > 0:
 | |
|         if exp_root:
 | |
|             main_buf += write_chunk(b"NODE",b"".join(root_buf) + b"".join(node_buf))
 | |
|         else:
 | |
|             main_buf += b"".join(node_buf)
 | |
| 
 | |
|         node_buf = []
 | |
|         root_buf = []
 | |
| 
 | |
|     if DEBUG: print("</node>")
 | |
| 
 | |
|     return main_buf
 | |
| 
 | |
| # ==== Write NODE MESH Chunk ====
 | |
| def write_node_mesh(obj,obj_count,arm_action,exp_root):
 | |
|     global vertex_groups
 | |
|     vertex_groups = []
 | |
|     mesh_buf = bytearray()
 | |
|     temp_buf = bytearray()
 | |
| 
 | |
|     if arm_action:
 | |
|         data = obj.data
 | |
|     elif b3d_parameters.get("apply-modifiers"):
 | |
|         data = obj.to_mesh(the_scene, True, 'PREVIEW') # Apply modifiers
 | |
|     else:
 | |
|         data = obj.data
 | |
|     
 | |
|     temp_buf += write_int(-1) #Brush ID
 | |
|     temp_buf += write_node_mesh_vrts(obj, data, obj_count, arm_action, exp_root) #NODE MESH VRTS
 | |
|     temp_buf += write_node_mesh_tris(obj, data, obj_count, arm_action, exp_root) #NODE MESH TRIS
 | |
| 
 | |
|     if len(temp_buf) > 0:
 | |
|         mesh_buf += write_chunk(b"MESH",temp_buf)
 | |
|         temp_buf = ""
 | |
| 
 | |
|     return mesh_buf
 | |
| 
 | |
| def build_vertex_groups(data):
 | |
|     for f in getFaces(data):
 | |
|         for v in f.vertices:
 | |
|             vertex_groups.append({})
 | |
| 
 | |
| 
 | |
| # ==== Write NODE MESH VRTS Chunk ====
 | |
| def write_node_mesh_vrts(obj, data, obj_count, arm_action, exp_root):
 | |
|     vrts_buf = bytearray()
 | |
|     temp_buf = []
 | |
|     obj_flags = 0
 | |
|     
 | |
|     #global time_in_a
 | |
|     #global time_in_b
 | |
|     #global time_in_b1
 | |
|     #global time_in_b2
 | |
|     #global time_in_b3
 | |
|     #global time_in_b4
 | |
| 
 | |
|     #data = obj.getData(mesh = True)
 | |
|     global the_scene
 | |
|     
 | |
|     # FIXME: port to 2.5 API?
 | |
|     #orig_uvlayer = data.activeUVLayer
 | |
| 
 | |
|     if b3d_parameters.get("vertex-normals"):
 | |
|         obj_flags += 1
 | |
| 
 | |
|     #if b3d_parameters.get("vertex-colors") and data.getColorLayerNames():
 | |
|     if b3d_parameters.get("vertex-colors") and len(getVertexColors(data)) > 0:
 | |
|         obj_flags += 2
 | |
| 
 | |
|     temp_buf.append(write_int(obj_flags)) #Flags
 | |
|     #temp_buf += write_int(len(data.getUVLayerNames())) #UV Set
 | |
|     temp_buf.append(write_int(len(getUVTextures(data)))) #UV Set
 | |
|     temp_buf.append(write_int(2)) #UV Set Size
 | |
| 
 | |
|     # ---- Prepare the mesh "stack"
 | |
|     build_vertex_groups(data)
 | |
|     
 | |
|     # ---- Fill the mesh "stack"
 | |
|     if DEBUG: print("")
 | |
|     if DEBUG: print("        <!-- Building vertex_groups -->\n")
 | |
| 
 | |
|     ivert = -1
 | |
| 
 | |
| 
 | |
|     #if PROGRESS_VERBOSE:
 | |
|     #    progress = 0
 | |
|     #    print("    vertex_groups, face:",0,"/",len(getFaces(data)))
 | |
|     
 | |
|     the_scene.frame_set(1,subframe=0.0)
 | |
|     
 | |
|     if b3d_parameters.get("local-space"):
 | |
|         mesh_matrix = mathutils.Matrix()
 | |
|     else:
 | |
|         mesh_matrix = obj.matrix_world.copy()
 | |
|     
 | |
|     #import time
 | |
|     
 | |
|     uvdata = getUVTextures(data)
 | |
|     uv_layers_count = len(uvdata)
 | |
|     uv_textures = {}
 | |
|     weldable_vertices = {}
 | |
|     vertex_id_mapping = {}
 | |
|     for face in getFaces(data):
 | |
|         for vertex_index,vert in enumerate(face.vertices):
 | |
|             #for id,vert in enumerate(data.vertices):
 | |
|             
 | |
|             if vert not in uv_textures:
 | |
|                 uv_textures[vert] = {}
 | |
|             if face not in uv_textures[vert]:
 | |
|                 uv_textures[vert][face] = {}
 | |
|             
 | |
|             for iuvlayer in range(uv_layers_count):
 | |
|                 if vertex_index == 0:
 | |
|                     uv_textures[vert][face][iuvlayer] = uvdata[iuvlayer].data[face.index].uv1
 | |
|                 elif vertex_index == 1:
 | |
|                     uv_textures[vert][face][iuvlayer] = uvdata[iuvlayer].data[face.index].uv2
 | |
|                 elif vertex_index == 2:
 | |
|                     uv_textures[vert][face][iuvlayer] = uvdata[iuvlayer].data[face.index].uv3
 | |
|                 elif vertex_index == 3:
 | |
|                     uv_textures[vert][face][iuvlayer] = uvdata[iuvlayer].data[face.index].uv4
 | |
|     
 | |
|     for idVertex, vertexFaces in uv_textures.items():
 | |
|         is_weldable = True
 | |
|         
 | |
|         for iuvlayer in range(uv_layers_count):
 | |
|             u = None
 | |
|             v = None
 | |
|             for idFace, face in vertexFaces.items():
 | |
|                 if iuvlayer not in face:
 | |
|                     continue
 | |
|                 faceuvlayer = face[iuvlayer]
 | |
|                 if u is None:
 | |
|                     u = round(faceuvlayer[0]*1000)
 | |
|                     v = round(faceuvlayer[1]*1000)
 | |
|                 else:
 | |
|                     if round(faceuvlayer[0] * 1000) != u or round(faceuvlayer[1]*1000) != v:
 | |
|                         is_weldable = False
 | |
|                         break
 | |
|             if not is_weldable:
 | |
|                 break
 | |
| 
 | |
|         weldable_vertices[idVertex] = is_weldable
 | |
|         
 | |
|     
 | |
|     #print('uv_textures', uv_textures)
 | |
|     #print('weldable_vertices', weldable_vertices)
 | |
|     
 | |
|     for face in getFaces(data):
 | |
|         
 | |
|         if DEBUG: print("        <!-- Face",face.index,"-->")
 | |
|         
 | |
|         #if PROGRESS_VERBOSE:
 | |
|         #    progress += 1
 | |
|         #    if (progress % 50 == 0): print("    vertex_groups, face:",progress,"/",len(data.faces))
 | |
|         
 | |
|         per_face_vertices[face.index] = []
 | |
|         
 | |
|         for vertex_id,vert in enumerate(face.vertices):
 | |
|             
 | |
|             if vert in weldable_vertices and weldable_vertices[vert] and vert in vertex_id_mapping:
 | |
|                 per_face_vertices[face.index].append(vertex_id_mapping[vert])
 | |
|                 continue
 | |
|             
 | |
|             ivert += 1
 | |
|             vertex_id_mapping[vert] = ivert    
 | |
|             per_face_vertices[face.index].append(ivert)
 | |
|             
 | |
|             #a = time.time()
 | |
|             
 | |
|             if arm_action:
 | |
|                 v = mesh_matrix * data.vertices[vert].co
 | |
|                 vert_matrix = mathutils.Matrix.Translation(v)
 | |
|             else:
 | |
|                 vert_matrix = mathutils.Matrix.Translation(data.vertices[vert].co)
 | |
| 
 | |
|             vert_matrix *= TRANS_MATRIX
 | |
|             vcoord = vert_matrix.to_translation()
 | |
| 
 | |
|             temp_buf.append(write_float_triplet(vcoord.x, vcoord.z, vcoord.y))
 | |
| 
 | |
|             #b = time.time()
 | |
|             #time_in_a += b - a
 | |
|             
 | |
|             if b3d_parameters.get("vertex-normals"):
 | |
|                 norm_matrix = mathutils.Matrix.Translation(data.vertices[vert].normal)
 | |
| 
 | |
|                 if arm_action:
 | |
|                     norm_matrix *= mesh_matrix
 | |
| 
 | |
|                 norm_matrix *= TRANS_MATRIX
 | |
|                 normal_vector = norm_matrix.to_translation()
 | |
|                 
 | |
|                 temp_buf.append(write_float_triplet(normal_vector.x,  #NX
 | |
|                                                     normal_vector.z,  #NY
 | |
|                                                     normal_vector.y)) #NZ
 | |
| 
 | |
|             #c = time.time()
 | |
|             #time_in_b += c - b
 | |
| 
 | |
|             if b3d_parameters.get("vertex-colors") and len(getVertexColors(data)) > 0:
 | |
|                 vertex_colors = getVertexColors(data)
 | |
|                 if vertex_id == 0:
 | |
|                     vcolor = vertex_colors[0].data[face.index].color1
 | |
|                 elif vertex_id == 1:
 | |
|                     vcolor = vertex_colors[0].data[face.index].color2
 | |
|                 elif vertex_id == 2:
 | |
|                     vcolor = vertex_colors[0].data[face.index].color3
 | |
|                 elif vertex_id == 3:
 | |
|                     vcolor = vertex_colors[0].data[face.index].color4
 | |
|                 
 | |
|                 valpha = 1.0
 | |
|                 if (len(vertex_colors) > 1):
 | |
|                     if vertex_id == 0:
 | |
|                         valpha = vertex_colors[1].data[face.index].color1.r
 | |
|                     elif vertex_id == 1:
 | |
|                         valpha = vertex_colors[1].data[face.index].color2.r
 | |
|                     elif vertex_id == 2:
 | |
|                         valpha = vertex_colors[1].data[face.index].color3.r
 | |
|                     elif vertex_id == 3:
 | |
|                         valpha = vertex_colors[1].data[face.index].color4.r
 | |
|                 
 | |
|                 temp_buf.append(write_float_quad(vcolor.r, #R
 | |
|                                                  vcolor.g, #G
 | |
|                                                  vcolor.b, #B
 | |
|                                                  valpha))  #A (FIXME?)
 | |
|             
 | |
|             #d = time.time()
 | |
|             #time_in_b1 += d - c
 | |
|             
 | |
|             for vg in obj.vertex_groups:
 | |
|                 w = 0.0
 | |
|                 try:
 | |
|                     w = vg.weight(vert)
 | |
|                 except:
 | |
|                     pass
 | |
|                 vertex_groups[ivert][vg.name] = w
 | |
|             
 | |
|             #e = time.time()
 | |
|             #time_in_b2 += e - d
 | |
|             
 | |
|             for iuvlayer in range(uv_layers_count):
 | |
|                 uv = [10, 10]
 | |
|                 if vert in uv_textures:
 | |
|                     vertex_uv = uv_textures[vert]
 | |
|                     
 | |
|                     if face in vertex_uv:
 | |
|                         vertex_face_uv = vertex_uv[face]
 | |
|                         
 | |
|                         if iuvlayer in vertex_face_uv:
 | |
|                             uv = vertex_face_uv[iuvlayer]
 | |
|                 
 | |
|                 temp_buf.append(write_float_couple(uv[0], 1-uv[1]) ) # U, V
 | |
|             
 | |
| 
 | |
|     
 | |
|     if DEBUG: print("")
 | |
|     
 | |
|     #c = time.time()
 | |
|     #time_in_b += c - b
 | |
|     #print("time_in_a = ",time_in_a)
 | |
|     #print("time_in_b = ",time_in_b)
 | |
|     #print("time_in_b1 = ", time_in_b1)
 | |
|     #print("time_in_b2 = ", time_in_b2)
 | |
|     #print("time_in_b3 = ", time_in_b3)
 | |
|     #print("time_in_b4 = ", time_in_b4)
 | |
| 
 | |
|     if len(temp_buf) > 0:
 | |
|         vrts_buf += write_chunk(b"VRTS",b"".join(temp_buf))
 | |
|         temp_buf = []
 | |
| 
 | |
|     return vrts_buf
 | |
| 
 | |
| # ==== Write NODE MESH TRIS Chunk ====
 | |
| def write_node_mesh_tris(obj, data, obj_count,arm_action,exp_root):
 | |
| 
 | |
|     global texture_count
 | |
| 
 | |
|     #FIXME?
 | |
|     #orig_uvlayer = data.activeUVLayer
 | |
| 
 | |
|     # An dictoriary that maps all brush-ids to a list of faces
 | |
|     # using this brush. This helps to sort the triangles by
 | |
|     # brush, creating less mesh buffer in irrlicht.
 | |
|     dBrushId2Face = {}
 | |
|     
 | |
|     if DEBUG: print("")
 | |
|     
 | |
|     for face in getFaces(data):
 | |
|         img_found = 0
 | |
|         face_stack = []
 | |
|         
 | |
|         uv_textures = getUVTextures(data)
 | |
|         uv_layer_count = len(uv_textures)
 | |
|         for iuvlayer,uvlayer in enumerate(uv_textures):
 | |
|             if iuvlayer < 8:
 | |
|                 
 | |
|                 if iuvlayer >= uv_layer_count:
 | |
|                     continue
 | |
|                 
 | |
|                 img_id = -1
 | |
|                 
 | |
|                 img = uv_textures[iuvlayer].data[face.index].image
 | |
|                 if img:
 | |
|                     
 | |
|                     if img.filepath in trimmed_paths:
 | |
|                         img_name = trimmed_paths[img.filepath]
 | |
|                     else:
 | |
|                         img_name = os.path.basename(img.filepath)
 | |
|                         trimmed_paths[img.filepath] = img_name
 | |
|                     
 | |
|                     img_found = 1
 | |
|                     if img_name in texs_stack:
 | |
|                         img_id = texs_stack[img_name][TEXTURE_ID]
 | |
| 
 | |
|                 face_stack.insert(iuvlayer,img_id)
 | |
| 
 | |
|         for i in range(len(face_stack),texture_count):
 | |
|             face_stack.append(-1)
 | |
| 
 | |
|         if img_found == 0:
 | |
|             brus_id = -1
 | |
|             if data.materials and data.materials[face.material_index]:
 | |
|                 mat_name = data.materials[face.material_index].name
 | |
|                 for i in range(len(brus_stack)):
 | |
|                     if brus_stack[i] == mat_name:
 | |
|                         brus_id = i
 | |
|                         break
 | |
|             else:
 | |
|                 for i in range(len(brus_stack)):
 | |
|                     if brus_stack[i] == face_stack:
 | |
|                         brus_id = i
 | |
|                         break
 | |
|         else:
 | |
|             brus_id = -1
 | |
|             for i in range(len(brus_stack)):
 | |
|                 if brus_stack[i] == face_stack:
 | |
|                     brus_id = i
 | |
|                     break
 | |
|             if brus_id == -1:
 | |
|                 print("Cannot find in brus stack : ", face_stack)
 | |
| 
 | |
|         if brus_id in dBrushId2Face:
 | |
|             dBrushId2Face[brus_id].append(face)
 | |
|         else:
 | |
|             dBrushId2Face[brus_id] = [face]
 | |
|         
 | |
|         if DEBUG: print("        <!-- Face",face.index,"in brush",brus_id,"-->")
 | |
|     
 | |
|     tris_buf = bytearray()
 | |
|     
 | |
|     if DEBUG: print("")
 | |
|     if DEBUG: print("        <!-- TRIS chunk -->")
 | |
|     
 | |
|     if PROGRESS_VERBOSE: progress = 0
 | |
|                 
 | |
|     for brus_id in dBrushId2Face.keys():
 | |
|         
 | |
|         if PROGRESS_VERBOSE:
 | |
|             progress += 1
 | |
|             print("BRUS:",progress,"/",len(dBrushId2Face.keys()))
 | |
|         
 | |
|         temp_buf = [write_int(brus_id)] #Brush ID
 | |
|         
 | |
|         if DEBUG: print("        <brush id=", brus_id, ">")
 | |
|         
 | |
|         if PROGRESS_VERBOSE: progress2 = 0
 | |
|                 
 | |
|         for face in dBrushId2Face[brus_id]:
 | |
|             
 | |
|             if PROGRESS_VERBOSE:
 | |
|                 progress2 += 1
 | |
|                 if (progress2 % 50 == 0): print("    TRIS:",progress2,"/",len(dBrushId2Face[brus_id]))
 | |
| 
 | |
|             vertices = per_face_vertices[face.index]
 | |
| 
 | |
|             temp_buf.append(write_int(vertices[2])) #A
 | |
|             temp_buf.append(write_int(vertices[1])) #B
 | |
|             temp_buf.append(write_int(vertices[0])) #C
 | |
| 
 | |
|             if DEBUG: print("            <face id=", vertices[2], vertices[1], vertices[0],"/> <!-- face",face.index,"-->")
 | |
| 
 | |
|             if len(face.vertices) == 4:
 | |
|                 temp_buf.append(write_int(vertices[3])) #A
 | |
|                 temp_buf.append(write_int(vertices[2])) #B
 | |
|                 temp_buf.append(write_int(vertices[0])) #C
 | |
|                 if DEBUG: print("            <face id=", vertices[3], vertices[2], vertices[0],"/> <!-- face",face.index,"-->")
 | |
| 
 | |
|         if DEBUG: print("        </brush>")
 | |
|         tris_buf += write_chunk(b"TRIS", b"".join(temp_buf))
 | |
| 
 | |
|     return tris_buf
 | |
| 
 | |
| # ==== Write NODE ANIM Chunk ====
 | |
| def write_node_anim(num_frames):
 | |
|     anim_buf = bytearray()
 | |
|     temp_buf = bytearray()
 | |
| 
 | |
|     temp_buf += write_int(0) #Flags
 | |
|     temp_buf += write_int(num_frames) #Frames
 | |
|     temp_buf += write_float(60) #FPS
 | |
| 
 | |
|     if len(temp_buf) > 0:
 | |
|         anim_buf += write_chunk(b"ANIM",temp_buf)
 | |
|         temp_buf = ""
 | |
| 
 | |
|     return anim_buf
 | |
| 
 | |
| # ==== Write NODE NODE Chunk ====
 | |
| def write_node_node(ibone):
 | |
|     node_buf = bytearray()
 | |
|     temp_buf = []
 | |
| 
 | |
|     bone = bone_stack[ibone]
 | |
| 
 | |
|     matrix = bone[BONE_PARENT_MATRIX]
 | |
|     temp_buf.append(write_string(bone[BONE_ITSELF].name)) #Node Name
 | |
|     
 | |
| 
 | |
| 
 | |
|     # FIXME: we should use the same matrix format everywhere to not require this
 | |
|     
 | |
|     position = matrix.to_translation()
 | |
|     if bone[BONE_PARENT]:
 | |
|         temp_buf.append(write_float_triplet(-position[0], position[2], position[1]))
 | |
|     else:
 | |
|         temp_buf.append(write_float_triplet(position[0], position[2], position[1]))
 | |
|     
 | |
|     
 | |
|     scale = matrix.to_scale()
 | |
|     temp_buf.append(write_float_triplet(scale[0], scale[2], scale[1]))
 | |
| 
 | |
|     quat = matrix.to_quaternion()
 | |
|     quat.normalize()
 | |
| 
 | |
|     temp_buf.append(write_float_quad(quat.w, quat.x, quat.z, quat.y))
 | |
| 
 | |
|     temp_buf.append(write_node_bone(ibone))
 | |
|     temp_buf.append(write_node_keys(ibone))
 | |
| 
 | |
|     for iibone in bone_stack:
 | |
|         if bone_stack[iibone][BONE_PARENT] == bone_stack[ibone][BONE_ITSELF]:
 | |
|             temp_buf.append(write_node_node(iibone))
 | |
| 
 | |
|     if len(temp_buf) > 0:
 | |
|         node_buf += write_chunk(b"NODE", b"".join(temp_buf))
 | |
|         temp_buf = []
 | |
| 
 | |
|     return node_buf
 | |
| 
 | |
| # ==== Write NODE BONE Chunk ====
 | |
| def write_node_bone(ibone):
 | |
|     bone_buf = bytearray()
 | |
|     temp_buf = []
 | |
| 
 | |
|     my_name = bone_stack[ibone][BONE_ITSELF].name
 | |
| 
 | |
|     for ivert in range(len(vertex_groups)):
 | |
|         if my_name in vertex_groups[ivert]:
 | |
|             vert_influ = vertex_groups[ivert][my_name]
 | |
|             #if DEBUG: print("        <bone name=",bone_stack[ibone][BONE_ITSELF].name,"face_vertex_id=", ivert + iuv,
 | |
|             #                " weigth=", vert_influ[1] , "/>")
 | |
|             temp_buf.append(write_int(ivert)) # Face Vertex ID
 | |
|             temp_buf.append(write_float(vert_influ)) #Weight
 | |
| 
 | |
|     bone_buf += write_chunk(b"BONE", b"".join(temp_buf))
 | |
|     temp_buf = []
 | |
| 
 | |
|     return bone_buf
 | |
| 
 | |
| # ==== Write NODE KEYS Chunk ====
 | |
| def write_node_keys(ibone):
 | |
|     keys_buf = bytearray()
 | |
|     temp_buf = []
 | |
| 
 | |
|     temp_buf.append(write_int(7)) #Flags
 | |
| 
 | |
|     my_name = bone_stack[ibone][BONE_ITSELF].name
 | |
| 
 | |
|     for ikeys in range(len(keys_stack)):
 | |
|         if keys_stack[ikeys][1] == my_name:
 | |
|             temp_buf.append(write_int(keys_stack[ikeys][0])) #Frame
 | |
| 
 | |
|             position = keys_stack[ikeys][2]
 | |
|             # FIXME: we should use the same matrix format everywhere and not require this
 | |
|             if b3d_parameters.get("local-space"):
 | |
|                 if bone_stack[ibone][BONE_PARENT]:
 | |
|                     temp_buf.append(write_float_triplet(-position[0], position[2], position[1]))
 | |
|                 else:
 | |
|                     temp_buf.append(write_float_triplet(position[0], position[2], position[1]))
 | |
|             else:
 | |
|                 temp_buf.append(write_float_triplet(-position[0], position[1], position[2]))
 | |
| 
 | |
|             scale = keys_stack[ikeys][3]
 | |
|             temp_buf.append(write_float_triplet(scale[0], scale[1], scale[2]))
 | |
| 
 | |
|             quat = keys_stack[ikeys][4]
 | |
|             quat.normalize()
 | |
| 
 | |
|             temp_buf.append(write_float_quad(quat.w, -quat.x, quat.y, quat.z))
 | |
|             #break
 | |
| 
 | |
|     keys_buf += write_chunk(b"KEYS",b"".join(temp_buf))
 | |
|     temp_buf = []
 | |
| 
 | |
|     return keys_buf
 | |
| 
 | |
| 
 | |
| # ==== CONFIRM OPERATOR ====
 | |
| class B3D_Confirm_Operator(bpy.types.Operator):
 | |
|     bl_idname = ("screen.b3d_confirm")
 | |
|     bl_label = ("File Exists, Overwrite?")
 | |
|     
 | |
|     def invoke(self, context, event):
 | |
|         wm = context.window_manager
 | |
|         return wm.invoke_props_dialog(self)
 | |
|     
 | |
|     def execute(self, context):
 | |
|         write_b3d_file(B3D_Confirm_Operator.filepath)
 | |
|         return {'FINISHED'}
 | |
| 
 | |
| 
 | |
| #class ObjectListItem(bpy.types.PropertyGroup):
 | |
| #    id = bpy.props.IntProperty(name="ID")
 | |
| #
 | |
| #bpy.utils.register_class(ObjectListItem)
 | |
|     
 | |
| # ==== EXPORT OPERATOR ====
 | |
| 
 | |
| class B3D_Export_Operator(bpy.types.Operator):
 | |
|     bl_idname = ("screen.b3d_export")
 | |
|     bl_label = ("B3D Export")
 | |
|     filepath = bpy.props.StringProperty(subtype="FILE_PATH")
 | |
| 
 | |
|     selected = bpy.props.BoolProperty(name="Export Selected Only", default=False)
 | |
|     vnormals = bpy.props.BoolProperty(name="Export Vertex Normals", default=True)
 | |
|     vcolors  = bpy.props.BoolProperty(name="Export Vertex Colors", default=True)
 | |
|     cameras  = bpy.props.BoolProperty(name="Export Cameras", default=False)
 | |
|     lights   = bpy.props.BoolProperty(name="Export Lights", default=False)
 | |
|     mipmap   = bpy.props.BoolProperty(name="Mipmap", default=False)
 | |
|     localsp  = bpy.props.BoolProperty(name="Use Local Space Coords", default=False)
 | |
|     applymodifiers = bpy.props.BoolProperty(name="Apply modifiers", default=True)
 | |
|     
 | |
|     overwrite_without_asking  = bpy.props.BoolProperty(name="Overwrite without asking", default=False)
 | |
|     
 | |
|     #skip_dialog = False
 | |
|     
 | |
|     #objects = bpy.props.CollectionProperty(type=ObjectListItem, options={'HIDDEN'})
 | |
|     
 | |
|     def invoke(self, context, event):
 | |
|         blend_filepath = context.blend_data.filepath
 | |
|         if not blend_filepath:
 | |
|             blend_filepath = "Untitled.b3d"
 | |
|         else:
 | |
|             blend_filepath = os.path.splitext(blend_filepath)[0] + ".b3d"
 | |
|         self.filepath = blend_filepath
 | |
|         
 | |
|         context.window_manager.fileselect_add(self)
 | |
|         return {'RUNNING_MODAL'}
 | |
|     
 | |
|     def execute(self, context):
 | |
|         
 | |
|         global b3d_parameters
 | |
|         global the_scene
 | |
|         b3d_parameters["export-selected"] = self.selected
 | |
|         b3d_parameters["vertex-normals" ] = self.vnormals
 | |
|         b3d_parameters["vertex-colors"  ] = self.vcolors
 | |
|         b3d_parameters["cameras"        ] = self.cameras
 | |
|         b3d_parameters["lights"         ] = self.lights
 | |
|         b3d_parameters["mipmap"         ] = self.mipmap
 | |
|         b3d_parameters["local-space"    ] = self.localsp
 | |
|         b3d_parameters["apply-modifiers"] = self.applymodifiers
 | |
|         
 | |
|         the_scene = context.scene
 | |
|         
 | |
|         if self.filepath == "":
 | |
|             return {'FINISHED'}
 | |
| 
 | |
|         if not self.filepath.endswith(".b3d"):
 | |
|             self.filepath += ".b3d"
 | |
| 
 | |
|         print("EXPORT", self.filepath," vcolor = ", self.vcolors)
 | |
|             
 | |
|         obj_list = []
 | |
|         try:
 | |
|             # FIXME: silly and ugly hack, the list of objects to export is passed through
 | |
|             #        a custom scene property
 | |
|             obj_list = context.scene.obj_list
 | |
|         except:
 | |
|             pass
 | |
|         
 | |
|         if len(obj_list) > 0:
 | |
|           
 | |
|             #objlist = []
 | |
|             #for a in self.objects:
 | |
|             #    objlist.append(bpy.data.objects[a.id])
 | |
|             #
 | |
|             #write_b3d_file(self.filepath, obj_list)
 | |
|             
 | |
|             write_b3d_file(self.filepath, obj_list)
 | |
|         else:
 | |
|             if os.path.exists(self.filepath) and not self.overwrite_without_asking:
 | |
|                 #self.report({'ERROR'}, "File Exists")
 | |
|                 B3D_Confirm_Operator.filepath = self.filepath
 | |
|                 bpy.ops.screen.b3d_confirm('INVOKE_DEFAULT')
 | |
|                 return {'FINISHED'}
 | |
|             else:
 | |
|                 write_b3d_file(self.filepath)
 | |
|         return {'FINISHED'}
 | |
| 
 | |
| 
 | |
| # Add to a menu
 | |
| def menu_func_export(self, context):
 | |
|     global the_scene
 | |
|     the_scene = context.scene
 | |
|     self.layout.operator(B3D_Export_Operator.bl_idname, text="B3D (.b3d)")
 | |
| 
 | |
| def register():
 | |
|     bpy.types.INFO_MT_file_export.append(menu_func_export)
 | |
|     bpy.utils.register_module(__name__)
 | |
| 
 | |
| def unregister():
 | |
|     bpy.types.INFO_MT_file_export.remove(menu_func_export)
 | |
| 
 | |
| if __name__ == "__main__":
 | |
|     register()
 | |
|     
 |