Guest User

Blender B3D Exporter

a guest
Aug 22nd, 2009
496
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 38.15 KB | None | 0 0
  1. #!BPY
  2. # -*- coding: utf-8 -*-
  3.  
  4. """
  5. Name: 'B3D Exporter (.b3d)...'
  6. Blender: 248.1
  7. Group: 'Export'
  8. Tooltip: 'Export to Blitz3D file format (.b3d)'
  9. """
  10. __author__ = ["Diego 'GaNDaLDF' Parisi"]
  11. __url__ = ["www.gandaldf.com"]
  12. __version__ = "2.07"
  13. __bpydoc__ = """\
  14. """
  15.  
  16. # BLITZ3D EXPORTER 2.07:
  17. # Copyright (C) 2009 by Diego "GaNDaLDF" Parisi  -  www.gandaldf.com
  18. #
  19. # Lightmap issue fixed by Capricorn 76 Pty. Ltd. - www.capricorn76.com
  20. # Objects parameter added by SuperTuxKart Team - www.supertuxkart.sourceforge.net
  21. #
  22. # LICENSE:
  23. # This program is free software; you can redistribute it and/or modify
  24. # it under the terms of the GNU General Public License as published by
  25. # the Free Software Foundation; either version 2 of the License, or
  26. # (at your option) any later version.
  27. #
  28. # This program is distributed in the hope that it will be useful,
  29. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  30. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  31. # GNU General Public License for more details.
  32. #
  33. # You should have received a copy of the GNU General Public License
  34. # along with this program; if not, write to the Free Software
  35. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  36.  
  37.  
  38. #If you get an error here, it might be
  39. #because you don't have Python installed.
  40. import Blender
  41. import BPyMesh
  42. import sys,os,os.path,struct,math,string
  43. from Blender import Mathutils
  44. from Blender.Mathutils import *
  45. from Blender import Draw,BGL
  46. from Blender.BGL import *
  47.  
  48. if not hasattr(sys,"argv"): sys.argv = ["???"]
  49.  
  50. #Events
  51. EVENT_ALL = 1
  52. EVENT_SEL = 2
  53. EVENT_NOR = 3
  54. EVENT_COL = 4
  55. EVENT_CAM = 5
  56. EVENT_LIG = 6
  57. EVENT_EXP = 7
  58. EVENT_QUI = 8
  59.  
  60. #Global Stacks
  61. flag_stack = []
  62. sets_stack = []
  63. texs_stack = []
  64. brus_stack = []
  65. mesh_stack = []
  66. bone_stack = []
  67. keys_stack = []
  68.  
  69. #Transformation Matrix
  70. TRANS_MATRIX = Mathutils.Matrix([-1,0,0,0],[0,0,1,0],[0,1,0,0],[0,0,0,1])
  71.  
  72. #Support Functions
  73. def write_int(value):
  74.     return struct.pack("<i",value)
  75.  
  76. def write_float(value):
  77.     return struct.pack("<f",round(value,4))
  78.  
  79. def write_string(value):
  80.     binary_format = "<%ds"%(len(value)+1)
  81.     return struct.pack(binary_format,value)
  82.  
  83. def write_chunk(name,value):
  84.     return name + write_int(len(value)) + value
  85.  
  86. #Write B3D File
  87. def write_b3d_file(filename, objects=[]):
  88.     global flag_stack, sets_stack, texs_stack
  89.     global brus_stack, mesh_stack, bone_stack, keys_stack
  90.  
  91.     #Global Stacks
  92.     sets_stack = []
  93.     texs_stack = []
  94.     brus_stack = []
  95.     mesh_stack = []
  96.     bone_stack = []
  97.     keys_stack = []
  98.     file_buf = ""
  99.     temp_buf = ""
  100.  
  101.     temp_buf += write_int(1) #Version
  102.     temp_buf += write_texs(objects) #TEXS
  103.     temp_buf += write_brus(objects) #BRUS
  104.     temp_buf += write_node(objects) #NODE
  105.  
  106.     if len(temp_buf) > 0:
  107.         file_buf += write_chunk("BB3D",temp_buf)
  108.         temp_buf = ""
  109.  
  110.     file = open(filename,'wb')
  111.     file.write(file_buf)
  112.     file.close()
  113.  
  114. #Write TEXS Chunk
  115. def write_texs(objects=[]):
  116.     texs_buf = ""
  117.     temp_buf = ""
  118.     layer_max = 0
  119.     obj_count = 0
  120.     set_wrote = 0
  121.  
  122.     if objects:
  123.         exp_obj = objects
  124.     else:
  125.         if flag_stack[1]:
  126.             exp_obj = Blender.Object.GetSelected()
  127.         else:
  128.             exp_obj = Blender.Object.Get()
  129.  
  130.     for obj in exp_obj:
  131.         if obj.type == "Mesh":
  132.             set_count = 0
  133.             set_wrote = 0
  134.             data = obj.getData(mesh = True)
  135.             orig_uvlayer = data.activeUVLayer
  136.             layer_set = [[],[],[],[],[],[],[],[]]
  137.             sets_stack.append([[],[],[],[],[],[],[],[]])
  138.  
  139.             if len(data.getUVLayerNames()) <= 8:
  140.                 if len(data.getUVLayerNames()) > layer_max:
  141.                     layer_max = len(data.getUVLayerNames())
  142.             else:
  143.                 layer_max = 8
  144.  
  145.             for face in data.faces:
  146.                 for iuvlayer,uvlayer in enumerate(data.getUVLayerNames()):
  147.                     if iuvlayer < 8:
  148.                         data.activeUVLayer = uvlayer
  149.                         layer_set[iuvlayer].append(face.uv)
  150.  
  151.             for i in xrange(len(data.getUVLayerNames())):
  152.                 if set_wrote:
  153.                     set_count += 1
  154.                     set_wrote = 0
  155.  
  156.                 for iuvlayer in xrange(i,len(data.getUVLayerNames())):
  157.                     if layer_set[i] == layer_set[iuvlayer]:
  158.                         if sets_stack[obj_count][iuvlayer] == []:
  159.                             if set_count == 0:
  160.                                 tex_flag = 1
  161.                             elif set_count == 1:
  162.                                 tex_flag = 65536
  163.                             elif set_count > 1:
  164.                                 tex_flag = 1
  165.                             sets_stack[obj_count][iuvlayer] = tex_flag
  166.                             set_wrote = 1
  167.  
  168.             for face in data.faces:
  169.                 for iuvlayer,uvlayer in enumerate(data.getUVLayerNames()):
  170.                     if iuvlayer < 8:
  171.                         data.activeUVLayer = uvlayer
  172.                         if face.image:
  173.                             if not [face.image.name,sets_stack[obj_count][iuvlayer]] in texs_stack:
  174.                                 texs_stack.append([face.image.name,sets_stack[obj_count][iuvlayer]])
  175.                                 temp_buf += write_string(Blender.sys.basename(face.image.getFilename())) #Texture File Name
  176.                                 temp_buf += write_int(sets_stack[obj_count][iuvlayer]) #Flags
  177.                                 temp_buf += write_int(2)   #Blend
  178.                                 temp_buf += write_float(0) #X_Pos
  179.                                 temp_buf += write_float(0) #Y_Pos
  180.                                 temp_buf += write_float(1) #X_Scale
  181.                                 temp_buf += write_float(1) #Y_Scale
  182.                                 temp_buf += write_float(0) #Rotation
  183.  
  184.             obj_count += 1
  185.  
  186.             if orig_uvlayer:
  187.                 data.activeUVLayer = orig_uvlayer
  188.  
  189.     texs_stack.append(layer_max)
  190.  
  191.     if len(temp_buf) > 0:
  192.         texs_buf += write_chunk("TEXS",temp_buf)
  193.         temp_buf = ""
  194.  
  195.     return texs_buf
  196.  
  197. #Write BRUS Chunk
  198. def write_brus(objects=[]):
  199.     brus_buf = ""
  200.     temp_buf = ""
  201.     mat_count = 0
  202.     obj_count = 0
  203.  
  204.     if objects:
  205.         exp_obj = objects
  206.     else:
  207.         if flag_stack[1]:
  208.             exp_obj = Blender.Object.GetSelected()
  209.         else:
  210.             exp_obj = Blender.Object.Get()
  211.  
  212.     for obj in exp_obj:
  213.         if obj.type == "Mesh":
  214.             data = obj.getData(mesh = True)
  215.             orig_uvlayer = data.activeUVLayer
  216.  
  217.             for face in data.faces:
  218.                 img_found = 0
  219.                 face_stack = []
  220.                 for iuvlayer,uvlayer in enumerate(data.getUVLayerNames()):
  221.                     if iuvlayer < 8:
  222.                         data.activeUVLayer = uvlayer
  223.                         if data.faceUV and face.image:
  224.                             img_found = 1
  225.                             for i in xrange(len(texs_stack)-1):
  226.                                 if texs_stack[i][0] == face.image.name:
  227.                                     if texs_stack[i][1] == sets_stack[obj_count][iuvlayer]:
  228.                                         img_id = i
  229.                         else:
  230.                             img_id = -1
  231.  
  232.                         face_stack.insert(iuvlayer,img_id)
  233.  
  234.                 for i in xrange(len(face_stack),texs_stack[-1]):
  235.                     face_stack.append(-1)
  236.  
  237.                 if not img_found:
  238.                     if data.materials:
  239.                         if data.materials[face.mat]:
  240.                             mat_data = data.materials[face.mat]
  241.                             mat_colr = mat_data.rgbCol[0]
  242.                             mat_colg = mat_data.rgbCol[1]
  243.                             mat_colb = mat_data.rgbCol[2]
  244.                             mat_alpha = mat_data.getAlpha()
  245.                             mat_name = mat_data.name
  246.  
  247.                             if not mat_name in brus_stack:
  248.                                 brus_stack.append(mat_name)
  249.                                 temp_buf += write_string(mat_name) #Brush Name
  250.                                 temp_buf += write_float(mat_colr)  #Red
  251.                                 temp_buf += write_float(mat_colg)  #Green
  252.                                 temp_buf += write_float(mat_colb)  #Blue
  253.                                 temp_buf += write_float(mat_alpha) #Alpha
  254.                                 temp_buf += write_float(0)         #Shininess
  255.                                 temp_buf += write_int(1)           #Blend
  256.                                 if flag_stack[3] and data.getColorLayerNames():
  257.                                     temp_buf += write_int(2) #Fx
  258.                                 else:
  259.                                     temp_buf += write_int(0) #Fx
  260.  
  261.                                 for i in face_stack:
  262.                                     temp_buf += write_int(i) #Texture ID
  263.                     else:
  264.                         if flag_stack[3] and data.getColorLayerNames():
  265.                             if not face_stack in brus_stack:
  266.                                 brus_stack.append(face_stack)
  267.                                 mat_count += 1
  268.                                 temp_buf += write_string("Brush.%.3i"%mat_count) #Brush Name
  269.                                 temp_buf += write_float(1) #Red
  270.                                 temp_buf += write_float(1) #Green
  271.                                 temp_buf += write_float(1) #Blue
  272.                                 temp_buf += write_float(1) #Alpha
  273.                                 temp_buf += write_float(0) #Shininess
  274.                                 temp_buf += write_int(1)   #Blend
  275.                                 temp_buf += write_int(2)   #Fx
  276.  
  277.                                 for i in face_stack:
  278.                                     temp_buf += write_int(i) #Texture ID
  279.                 else:
  280.                     if not face_stack in brus_stack:
  281.                         brus_stack.append(face_stack)
  282.                         mat_count += 1
  283.                         temp_buf += write_string("Brush.%.3i"%mat_count) #Brush Name
  284.                         temp_buf += write_float(1) #Red
  285.                         temp_buf += write_float(1) #Green
  286.                         temp_buf += write_float(1) #Blue
  287.                         temp_buf += write_float(1) #Alpha
  288.                         temp_buf += write_float(0) #Shininess
  289.                         temp_buf += write_int(1)   #Blend
  290.                         if flag_stack[3] and data.getColorLayerNames():
  291.                             temp_buf += write_int(2) #Fx
  292.                         else:
  293.                             temp_buf += write_int(0) #Fx
  294.  
  295.                         for i in face_stack:
  296.                             temp_buf += write_int(i) #Texture ID
  297.  
  298.             obj_count += 1
  299.  
  300.             if orig_uvlayer:
  301.                 data.activeUVLayer = orig_uvlayer
  302.  
  303.     if len(temp_buf) > 0:
  304.         brus_buf += write_chunk("BRUS",write_int(texs_stack[-1]) + temp_buf) #N Texs
  305.         temp_buf = ""
  306.  
  307.     return brus_buf
  308.  
  309. #Write NODE Chunk
  310. def write_node(objects=[]):
  311.     global bone_stack
  312.     global keys_stack
  313.     root_buf = ""
  314.     node_buf = ""
  315.     main_buf = ""
  316.     temp_buf = ""
  317.     obj_count = 0
  318.     amb_light = 0
  319.  
  320.     num_mesh = 0
  321.     num_ligs = 0
  322.     num_cams = 0
  323.     num_lorc = 0
  324.     exp_scn = Blender.Scene.GetCurrent()
  325.     exp_con = exp_scn.getRenderingContext()
  326.  
  327.     first_frame = Blender.Draw.Create(exp_con.startFrame())
  328.     last_frame = Blender.Draw.Create(exp_con.endFrame())
  329.     num_frames = last_frame.val - first_frame.val
  330.  
  331.     if objects:
  332.         exp_obj = objects
  333.     else:
  334.         if flag_stack[1]:
  335.             exp_obj = Blender.Object.GetSelected()
  336.         else:
  337.             exp_obj = Blender.Object.Get()
  338.  
  339.     for obj in exp_obj:
  340.         if obj.type == "Mesh":
  341.             num_mesh += 1
  342.         if obj.type == "Camera":
  343.             num_cams += 1
  344.         if obj.type == "Lamp":
  345.             num_ligs += 1
  346.  
  347.     if flag_stack[4] == 1:
  348.         num_lorc += num_cams
  349.  
  350.     if flag_stack[5] == 1:
  351.         num_lorc += 1
  352.         num_lorc += num_ligs
  353.  
  354.     if num_mesh + num_lorc > 1:
  355.         exp_root = 1
  356.     else:
  357.         exp_root = 0
  358.  
  359.     if exp_root:
  360.         root_buf += write_string("ROOT") #Node Name
  361.  
  362.         root_buf += write_float(0) #Position X
  363.         root_buf += write_float(0) #Position Y
  364.         root_buf += write_float(0) #Position Z
  365.  
  366.         root_buf += write_float(1) #Scale X
  367.         root_buf += write_float(1) #Scale Y
  368.         root_buf += write_float(1) #Scale Z
  369.  
  370.         root_buf += write_float(1) #Rotation W
  371.         root_buf += write_float(0) #Rotation X
  372.         root_buf += write_float(0) #Rotation Y
  373.         root_buf += write_float(0) #Rotation Z
  374.  
  375.     for obj in exp_obj:
  376.         if obj.type == "Mesh":
  377.             bone_stack = []
  378.             keys_stack = []
  379.             data = obj.getData(mesh = True)
  380.  
  381.             arm_action = None
  382.             if obj.getParent():
  383.                 if obj.getParent().type == "Armature":
  384.                     arm = obj.getParent()
  385.                     if arm.getAction():
  386.                         arm_action = arm.getAction()
  387.  
  388.             if arm_action:
  389.                 matrix = Matrix()
  390.  
  391.                 temp_buf += write_string(obj.name) #Node Name
  392.  
  393.                 position = matrix.translationPart()
  394.                 temp_buf += write_float(-position[0]) #Position X
  395.                 temp_buf += write_float(position[1])  #Position Y
  396.                 temp_buf += write_float(position[2])  #Position Z
  397.  
  398.                 scale = matrix.scalePart()
  399.                 temp_buf += write_float(scale[0]) #Scale X
  400.                 temp_buf += write_float(scale[2]) #Scale Y
  401.                 temp_buf += write_float(scale[1]) #Scale Z
  402.  
  403.                 quat = matrix.toQuat()
  404.                 quat.normalize()
  405.  
  406.                 temp_buf += write_float(quat.w) #Rotation W
  407.                 temp_buf += write_float(quat.x) #Rotation X
  408.                 temp_buf += write_float(quat.z) #Rotation Y
  409.                 temp_buf += write_float(quat.y) #Rotation Z
  410.             else:
  411.                 matrix = obj.getMatrix("worldspace")
  412.                 matrix *= TRANS_MATRIX
  413.  
  414.                 temp_buf += write_string(obj.name) #Node Name
  415.  
  416.                 position = matrix.translationPart()
  417.                 temp_buf += write_float(-position[0]) #Position X
  418.                 temp_buf += write_float(position[1])  #Position Y
  419.                 temp_buf += write_float(position[2])  #Position Z
  420.  
  421.                 scale = matrix.scalePart()
  422.                 temp_buf += write_float(scale[0]) #Scale X
  423.                 temp_buf += write_float(scale[2]) #Scale Y
  424.                 temp_buf += write_float(scale[1]) #Scale Z
  425.  
  426.                 matrix *= RotationMatrix(180,4,"y")
  427.                 matrix *= RotationMatrix(90,4,"x")
  428.                 quat = matrix.toQuat()
  429.                 quat.normalize()
  430.  
  431.                 temp_buf += write_float(quat.w) #Rotation W
  432.                 temp_buf += write_float(quat.x) #Rotation X
  433.                 temp_buf += write_float(quat.z) #Rotation Y
  434.                 temp_buf += write_float(quat.y) #Rotation Z
  435.  
  436.             if arm_action:
  437.                 Blender.Set("curframe",0)
  438.                 Blender.Window.Redraw()
  439.  
  440.                 data = arm.getData()
  441.                 arm_matrix = arm.getMatrix("worldspace")
  442.                 arm_matrix *= TRANS_MATRIX.invert()
  443.  
  444.                 def read_armature(arm_matrix,bone,parent = None):
  445.                     if (parent and not bone.parent.name == parent.name):
  446.                         return
  447.  
  448.                     matrix = Blender.Mathutils.Matrix(bone.matrix["ARMATURESPACE"])
  449.  
  450.                     if parent:
  451.                         par_matrix = matrix * Blender.Mathutils.Matrix(parent.matrix["ARMATURESPACE"]).invert()
  452.                     else:
  453.                         par_matrix = matrix * arm_matrix
  454.  
  455.                     bone_stack.append([par_matrix,parent,bone])
  456.  
  457.                     if bone.children:
  458.                         for child in bone.children: read_armature(arm_matrix,child,bone)
  459.  
  460.                 for bone in data.bones.values():
  461.                     if not bone.parent:
  462.                         read_armature(arm_matrix,bone)
  463.  
  464.                 arm_action.setActive(arm)
  465.                 frame_count = first_frame.val
  466.  
  467.                 while frame_count <= last_frame.val:
  468.                     Blender.Set("curframe",int(frame_count))
  469.                     Blender.Window.Redraw()
  470.                     arm_pose = arm.getPose()
  471.                     arm_matrix = arm.getMatrix("worldspace")
  472.                     arm_matrix *= TRANS_MATRIX
  473.  
  474.                     for bone_name in data.bones.keys():
  475.                         bone_matrix = Blender.Mathutils.Matrix(arm_pose.bones[bone_name].poseMatrix)
  476.  
  477.                         for ibone in xrange(len(bone_stack)):
  478.                             if bone_stack[ibone][2].name == bone_name:
  479.                                 if bone_stack[ibone][1]:
  480.                                     par_matrix = Blender.Mathutils.Matrix(arm_pose.bones[bone_stack[ibone][1].name].poseMatrix)
  481.                                     bone_matrix *= par_matrix.invert()
  482.                                 else:
  483.                                     bone_matrix *= arm_matrix
  484.  
  485.                                 bone_loc = bone_matrix.translationPart()
  486.                                 bone_rot = bone_matrix.rotationPart().toQuat()
  487.                                 bone_rot.normalize()
  488.                                 bone_sca = bone_matrix.scalePart()
  489.                                 keys_stack.append([frame_count - first_frame.val,bone_name,bone_loc,bone_sca,bone_rot])
  490.  
  491.                     frame_count += 1
  492.  
  493.                 Blender.Set("curframe",0)
  494.                 Blender.Window.Redraw()
  495.  
  496.             temp_buf += write_node_mesh(obj,obj_count,arm_action,exp_root) #NODE MESH
  497.  
  498.             if arm_action:
  499.                 temp_buf += write_node_anim(num_frames) #NODE ANIM
  500.  
  501.                 for ibone in xrange(len(bone_stack)):
  502.                     if not bone_stack[ibone][1]:
  503.                         temp_buf += write_node_node(ibone) #NODE NODE
  504.  
  505.             obj_count += 1
  506.  
  507.             if len(temp_buf) > 0:
  508.                 node_buf += write_chunk("NODE",temp_buf)
  509.                 temp_buf = ""
  510.  
  511.         if flag_stack[4]:
  512.             if obj.type == "Camera":
  513.                 data = obj.getData()
  514.                 matrix = obj.getMatrix("worldspace")
  515.                 matrix *= TRANS_MATRIX
  516.  
  517.                 if data.type == "ortho":
  518.                     cam_type = 2
  519.                     cam_zoom = round(data.scale,4)
  520.                 else:
  521.                     cam_type = 1
  522.                     cam_zoom = round(data.lens,4)
  523.  
  524.                 cam_near = round(data.clipStart,4)
  525.                 cam_far = round(data.clipEnd,4)
  526.  
  527.                 node_name = ("CAMS"+"\n%s"%obj.name+"\n%s"%cam_type+\
  528.                              "\n%s"%cam_zoom+"\n%s"%cam_near+"\n%s"%cam_far)
  529.                 temp_buf += write_string(node_name) #Node Name
  530.  
  531.                 position = matrix.translationPart()
  532.                 temp_buf += write_float(-position[0]) #Position X
  533.                 temp_buf += write_float(position[1])  #Position Y
  534.                 temp_buf += write_float(position[2])  #Position Z
  535.  
  536.                 scale = matrix.scalePart()
  537.                 temp_buf += write_float(scale[0]) #Scale X
  538.                 temp_buf += write_float(scale[1]) #Scale Y
  539.                 temp_buf += write_float(scale[2]) #Scale Z
  540.  
  541.                 matrix *= RotationMatrix(180,4,"y")
  542.                 quat = matrix.toQuat()
  543.                 quat.normalize()
  544.  
  545.                 temp_buf += write_float(quat.w)  #Rotation W
  546.                 temp_buf += write_float(quat.x)  #Rotation X
  547.                 temp_buf += write_float(quat.y)  #Rotation Y
  548.                 temp_buf += write_float(-quat.z) #Rotation Z
  549.  
  550.                 if len(temp_buf) > 0:
  551.                     node_buf += write_chunk("NODE",temp_buf)
  552.                     temp_buf = ""
  553.  
  554.         if flag_stack[5]:
  555.             if amb_light == 0:
  556.                 data = Blender.World.GetCurrent()
  557.  
  558.                 amb_light = 1
  559.                 amb_color = (int(data.amb[2]*255) |(int(data.amb[1]*255) << 8) | (int(data.amb[0]*255) << 16))
  560.  
  561.                 node_name = ("AMBI"+"\n%s"%amb_color)
  562.                 temp_buf += write_string(node_name) #Node Name
  563.  
  564.                 temp_buf += write_float(0) #Position X
  565.                 temp_buf += write_float(0) #Position Y
  566.                 temp_buf += write_float(0) #Position Z
  567.  
  568.                 temp_buf += write_float(1) #Scale X
  569.                 temp_buf += write_float(1) #Scale Y
  570.                 temp_buf += write_float(1) #Scale Z
  571.  
  572.                 temp_buf += write_float(1) #Rotation W
  573.                 temp_buf += write_float(0) #Rotation X
  574.                 temp_buf += write_float(0) #Rotation Y
  575.                 temp_buf += write_float(0) #Rotation Z
  576.  
  577.                 if len(temp_buf) > 0:
  578.                     node_buf += write_chunk("NODE",temp_buf)
  579.                     temp_buf = ""
  580.  
  581.             if obj.type == "Lamp":
  582.                 data = obj.getData()
  583.                 matrix = obj.getMatrix("worldspace")
  584.                 matrix *= TRANS_MATRIX
  585.  
  586.                 if data.type == 0:
  587.                     lig_type = 2
  588.                 elif data.type == 2:
  589.                     lig_type = 3
  590.                 else:
  591.                     lig_type = 1
  592.  
  593.                 lig_angle = round(data.spotSize,4)
  594.                 lig_color = (int(data.b*255) |(int(data.g*255) << 8) | (int(data.r*255) << 16))
  595.                 lig_range = round(data.dist,4)
  596.  
  597.                 node_name = ("LIGS"+"\n%s"%obj.name+"\n%s"%lig_type+\
  598.                              "\n%s"%lig_angle+"\n%s"%lig_color+"\n%s"%lig_range)
  599.                 temp_buf += write_string(node_name) #Node Name
  600.  
  601.                 position = matrix.translationPart()
  602.                 temp_buf += write_float(-position[0]) #Position X
  603.                 temp_buf += write_float(position[1])  #Position Y
  604.                 temp_buf += write_float(position[2])  #Position Z
  605.  
  606.                 scale = matrix.scalePart()
  607.                 temp_buf += write_float(scale[0]) #Scale X
  608.                 temp_buf += write_float(scale[1]) #Scale Y
  609.                 temp_buf += write_float(scale[2]) #Scale Z
  610.  
  611.                 matrix *= RotationMatrix(180,4,"y")
  612.                 quat = matrix.toQuat()
  613.                 quat.normalize()
  614.  
  615.                 temp_buf += write_float(quat.w)  #Rotation W
  616.                 temp_buf += write_float(quat.x)  #Rotation X
  617.                 temp_buf += write_float(quat.y)  #Rotation Y
  618.                 temp_buf += write_float(-quat.z) #Rotation Z
  619.  
  620.                 if len(temp_buf) > 0:
  621.                     node_buf += write_chunk("NODE",temp_buf)
  622.                     temp_buf = ""
  623.  
  624.     if len(node_buf) > 0:
  625.         if exp_root:
  626.             main_buf += write_chunk("NODE",root_buf + node_buf)
  627.         else:
  628.             main_buf += node_buf
  629.  
  630.         node_buf = ""
  631.         root_buf = ""
  632.  
  633.     return main_buf
  634.  
  635. #Write NODE MESH Chunk
  636. def write_node_mesh(obj,obj_count,arm_action,exp_root):
  637.     global mesh_stack
  638.     mesh_stack = []
  639.     mesh_buf = ""
  640.     temp_buf = ""
  641.  
  642.     temp_buf += write_int(-1) #Brush ID
  643.     temp_buf += write_node_mesh_vrts(obj,obj_count,arm_action,exp_root) #NODE MESH VRTS
  644.     temp_buf += write_node_mesh_tris(obj,obj_count,arm_action,exp_root) #NODE MESH TRIS
  645.  
  646.     if len(temp_buf) > 0:
  647.         mesh_buf += write_chunk("MESH",temp_buf)
  648.         temp_buf = ""
  649.  
  650.     return mesh_buf
  651.  
  652. #Write NODE MESH VRTS Chunk
  653. def write_node_mesh_vrts(obj,obj_count,arm_action,exp_root):
  654.     vrts_buf = ""
  655.     temp_buf = ""
  656.     obj_flags = 0
  657.     ids_count = 0
  658.  
  659.     data = obj.getData(mesh = True)
  660.     orig_uvlayer = data.activeUVLayer
  661.  
  662.     if flag_stack[2]:
  663.         obj_flags += 1
  664.  
  665.     if flag_stack[3] and data.getColorLayerNames():
  666.         obj_flags += 2
  667.  
  668.     temp_buf += write_int(obj_flags) #Flags
  669.     temp_buf += write_int(len(data.getUVLayerNames())) #UV Set
  670.     temp_buf += write_int(2) #UV Set Size
  671.  
  672.     for i in data.verts:
  673.         mesh_stack.append([-1,-1,-1,[],[[],[],[],[],[],[],[],[]],[]])
  674.  
  675.     for face in data.faces:
  676.         for ivert,vert in enumerate(face.verts):
  677.             if mesh_stack[vert.index][0] == -1:
  678.                 link_matrix = obj.getMatrix("worldspace")
  679.                 mesh_matrix = Matrix(link_matrix[0],link_matrix[1],link_matrix[2],link_matrix[3])
  680.                 vert_matrix = TranslationMatrix(vert.co)
  681.  
  682.                 if arm_action:
  683.                     vert_matrix *= mesh_matrix
  684.  
  685.                 vert_matrix *= TRANS_MATRIX
  686.                 vert_matrix = vert_matrix.translationPart()
  687.  
  688.                 mesh_stack[vert.index][0] = vert.index
  689.                 mesh_stack[vert.index][1] = vert_matrix
  690.  
  691.                 if flag_stack[2]:
  692.                     link_matrix = obj.getMatrix("worldspace")
  693.                     mesh_matrix = Matrix(link_matrix[0],link_matrix[1],link_matrix[2],link_matrix[3])
  694.                     norm_matrix = TranslationMatrix(vert.no)
  695.  
  696.                     if arm_action:
  697.                         norm_matrix *= mesh_matrix
  698.  
  699.                     norm_matrix *= TRANS_MATRIX
  700.                     norm_matrix = norm_matrix.translationPart()
  701.  
  702.                     mesh_stack[vert.index][2] = norm_matrix
  703.  
  704.                 if flag_stack[3] and data.getColorLayerNames():
  705.                     mesh_stack[vert.index][3] = face.col[ivert]
  706.  
  707.                 if data.vertexUV and not data.faceUV:
  708.             mesh_stack[vert.index][4][0].append([face.index,vert.uvco[0]])
  709.                 if not data.vertexUV and not data.faceUV:
  710.             mesh_stack[vert.index][4][0].append([face.index,[0.0,0.0]])
  711.  
  712.                 for vert_influ in data.getVertexInfluences(vert.index):
  713.                     mesh_stack[vert.index][5].append(vert_influ)
  714.  
  715.     if data.faceUV:
  716.         if not 65536 in sets_stack[obj_count]:
  717.             vert_opti = 1
  718.         else:
  719.             vert_opti = 0
  720.  
  721.         for iuvlayer,uvlayer in enumerate(data.getUVLayerNames()):
  722.             if iuvlayer < 8:
  723.                 data.activeUVLayer = uvlayer
  724.                 for face in data.faces:
  725.                     for ivert,vert in enumerate(face.verts):
  726.                         if vert_opti:
  727.                             if not face.uv[ivert] in mesh_stack[vert.index][4][iuvlayer]:
  728.                 mesh_stack[vert.index][4][iuvlayer].append([face.index,face.uv[ivert]])
  729.                         else:
  730.                 mesh_stack[vert.index][4][iuvlayer].append([face.index,face.uv[ivert]])
  731.  
  732.     if orig_uvlayer:
  733.         data.activeUVLayer = orig_uvlayer
  734.  
  735.     for ivert in xrange(len(mesh_stack)):
  736.     mesh_stack[ivert][0] = ids_count
  737.     for iuv in xrange(len(mesh_stack[ivert][4][0])):
  738.         ids_count += 1
  739.  
  740.             temp_buf += write_float(-mesh_stack[ivert][1].x) #X
  741.             temp_buf += write_float(mesh_stack[ivert][1].y)  #Y
  742.             temp_buf += write_float(mesh_stack[ivert][1].z)  #Z
  743.  
  744.             if flag_stack[2]:
  745.                 temp_buf += write_float(-mesh_stack[ivert][2].x) #NX
  746.                 temp_buf += write_float(mesh_stack[ivert][2].y)  #NY
  747.                 temp_buf += write_float(mesh_stack[ivert][2].z)  #NZ
  748.  
  749.             if flag_stack[3] and data.getColorLayerNames():
  750.                 temp_buf += write_float(mesh_stack[ivert][3].r/255.0) #R
  751.                 temp_buf += write_float(mesh_stack[ivert][3].g/255.0) #G
  752.                 temp_buf += write_float(mesh_stack[ivert][3].b/255.0) #B
  753.                 temp_buf += write_float(mesh_stack[ivert][3].a/255.0) #A
  754.  
  755.             for iuvlayer in xrange(len(data.getUVLayerNames())):
  756.                 temp_buf += write_float(mesh_stack[ivert][4][iuvlayer][iuv][1][0])  #U
  757.                 temp_buf += write_float(-mesh_stack[ivert][4][iuvlayer][iuv][1][1]) #V
  758.  
  759.     if len(temp_buf) > 0:
  760.         vrts_buf += write_chunk("VRTS",temp_buf)
  761.         temp_buf = ""
  762.  
  763.     return vrts_buf
  764.  
  765. #Write NODE MESH TRIS Chunk
  766. def write_node_mesh_tris(obj,obj_count,arm_action,exp_root):
  767.     tris_buf = ""
  768.     temp_buf = ""
  769.     last_brus = None
  770.     brus_written = 0
  771.  
  772.     data = obj.getData(mesh = True)
  773.     orig_uvlayer = data.activeUVLayer
  774.  
  775.     for face in data.faces:
  776.         img_found = 0
  777.         face_stack = []
  778.         for iuvlayer,uvlayer in enumerate(data.getUVLayerNames()):
  779.             if iuvlayer < 8:
  780.                 data.activeUVLayer = uvlayer
  781.                 if data.faceUV and face.image:
  782.                     img_found = 1
  783.                     for i in xrange(len(texs_stack)-1):
  784.                         if texs_stack[i][0] == face.image.name:
  785.                             if texs_stack[i][1] == sets_stack[obj_count][iuvlayer]:
  786.                                 img_id = i
  787.                 else:
  788.                     img_id = -1
  789.  
  790.                 face_stack.insert(iuvlayer,img_id)
  791.  
  792.         for i in xrange(len(face_stack),texs_stack[-1]):
  793.             face_stack.append(-1)
  794.  
  795.         if img_found == 0:
  796.             brus_id = -1
  797.             if data.materials:
  798.                 if data.materials[face.mat]:
  799.                     mat_name = data.materials[face.mat].name
  800.                     for i in xrange(len(brus_stack)):
  801.                         if brus_stack[i] == mat_name:
  802.                             brus_id = i
  803.             else:
  804.                 for i in xrange(len(brus_stack)):
  805.                     if brus_stack[i] == face_stack:
  806.                         brus_id = i
  807.         else:
  808.             brus_id = -1
  809.             for i in xrange(len(brus_stack)):
  810.                 if brus_stack[i] == face_stack:
  811.                     brus_id = i
  812.  
  813.         if last_brus <> brus_id:
  814.             if brus_written == 0:
  815.                 brus_written = 1
  816.             else:
  817.                 if len(temp_buf) > 0:
  818.                     tris_buf += write_chunk("TRIS",temp_buf)
  819.                     temp_buf = ""
  820.  
  821.             temp_buf += write_int(brus_id) #Brush ID
  822.             last_brus = brus_id
  823.  
  824.         face_id = [0,0,0,0]
  825.  
  826.         if data.faceUV:
  827.             for i in xrange(len(face.verts)):
  828.                 for iuv in xrange(len(mesh_stack[face.v[i].index][4][0])):
  829.                     if mesh_stack[face.v[i].index][4][0][iuv][0] == face.index:
  830.                         face_id[i] = mesh_stack[face.v[i].index][0] + iuv
  831.         else:
  832.             for i in xrange(len(face.verts)):
  833.                 face_id[i] = mesh_stack[face.v[i].index][0]
  834.  
  835.         temp_buf += write_int(face_id[2]) #A
  836.         temp_buf += write_int(face_id[1]) #B
  837.         temp_buf += write_int(face_id[0]) #C
  838.  
  839.         if len(face.v) == 4:
  840.             temp_buf += write_int(face_id[3]) #A
  841.             temp_buf += write_int(face_id[2]) #B
  842.             temp_buf += write_int(face_id[0]) #C
  843.  
  844.     if orig_uvlayer:
  845.         data.activeUVLayer = orig_uvlayer
  846.  
  847.     if len(temp_buf) > 0:
  848.         tris_buf += write_chunk("TRIS",temp_buf)
  849.         temp_buf = ""
  850.  
  851.     return tris_buf
  852.  
  853. #Write NODE ANIM Chunk
  854. def write_node_anim(num_frames):
  855.     anim_buf = ""
  856.     temp_buf = ""
  857.  
  858.     temp_buf += write_int(0) #Flags
  859.     temp_buf += write_int(num_frames) #Frames
  860.     temp_buf += write_float(60) #FPS
  861.  
  862.     if len(temp_buf) > 0:
  863.         anim_buf += write_chunk("ANIM",temp_buf)
  864.         temp_buf = ""
  865.  
  866.     return anim_buf
  867.  
  868. #Write NODE NODE Chunk
  869. def write_node_node(ibone):
  870.     node_buf = ""
  871.     temp_buf = ""
  872.  
  873.     matrix = bone_stack[ibone][0]
  874.     temp_buf += write_string(bone_stack[ibone][2].name) #Node Name
  875.  
  876.     position = matrix.translationPart()
  877.     temp_buf += write_float(-position[0]) #Position X
  878.     temp_buf += write_float(position[1])  #Position Y
  879.     temp_buf += write_float(position[2])  #Position Z
  880.  
  881.     scale = matrix.scalePart()
  882.     temp_buf += write_float(scale[0]) #Scale X
  883.     temp_buf += write_float(scale[1]) #Scale Y
  884.     temp_buf += write_float(scale[2]) #Scale Z
  885.  
  886.     quat = matrix.toQuat()
  887.     quat.normalize()
  888.  
  889.     temp_buf += write_float(quat.w)  #Rotation W
  890.     temp_buf += write_float(-quat.x) #Rotation X
  891.     temp_buf += write_float(quat.y)  #Rotation Y
  892.     temp_buf += write_float(quat.z)  #Rotation Z
  893.  
  894.     temp_buf += write_node_bone(ibone)
  895.     temp_buf += write_node_keys(ibone)
  896.  
  897.     for iibone in xrange(len(bone_stack)):
  898.         if bone_stack[iibone][1] == bone_stack[ibone][2]:
  899.             temp_buf += write_node_node(iibone)
  900.  
  901.     if len(temp_buf) > 0:
  902.         node_buf += write_chunk("NODE",temp_buf)
  903.         temp_buf = ""
  904.  
  905.     return node_buf
  906.  
  907. #Write NODE BONE Chunk
  908. def write_node_bone(ibone):
  909.     bone_buf = ""
  910.     temp_buf = ""
  911.  
  912.     for ivert in xrange(len(mesh_stack)):
  913.         for iuv in xrange(len(mesh_stack[ivert][4][0])):
  914.             for vert_influ in mesh_stack[ivert][5]:
  915.                 if bone_stack[ibone][2].name == vert_influ[0]:
  916.                     temp_buf += write_int(mesh_stack[ivert][0] + iuv) # Face Vertex ID
  917.                     temp_buf += write_float(vert_influ[1]) #Weight
  918.  
  919.     bone_buf += write_chunk("BONE",temp_buf)
  920.     temp_buf = ""
  921.  
  922.     return bone_buf
  923.  
  924. #Write NODE KEYS Chunk
  925. def write_node_keys(ibone):
  926.     keys_buf = ""
  927.     temp_buf = ""
  928.  
  929.     temp_buf += write_int(7) #Flags
  930.  
  931.     for ikeys in xrange(len(keys_stack)):
  932.         if keys_stack[ikeys][1] == bone_stack[ibone][2].name:
  933.             temp_buf += write_int(keys_stack[ikeys][0]) #Frame
  934.  
  935.             position = keys_stack[ikeys][2]
  936.             temp_buf += write_float(-position[0]) #Position X
  937.             temp_buf += write_float(position[1])  #Position Y
  938.             temp_buf += write_float(position[2])  #Position Z
  939.  
  940.             scale = keys_stack[ikeys][3]
  941.             temp_buf += write_float(scale[0]) #Scale X
  942.             temp_buf += write_float(scale[1]) #Scale Y
  943.             temp_buf += write_float(scale[2]) #Scale Z
  944.  
  945.             quat = keys_stack[ikeys][4]
  946.             quat.normalize()
  947.  
  948.             temp_buf += write_float(quat.w)  #Rotation W
  949.             temp_buf += write_float(-quat.x) #Rotation X
  950.             temp_buf += write_float(quat.y)  #Rotation Y
  951.             temp_buf += write_float(quat.z)  #Rotation Z
  952.  
  953.     keys_buf += write_chunk("KEYS",temp_buf)
  954.     temp_buf = ""
  955.  
  956.     return keys_buf
  957.  
  958. #Handle Event
  959. def handle_button(event):
  960.     global EVENT_ALL,EVENT_SEL
  961.     global EVENT_NOR,EVENT_COL,EVENT_CAM,EVENT_LIG
  962.     global EVENT_EXP,EVENT_QUI
  963.  
  964.     if event == EVENT_ALL:
  965.         flag_stack[0] = 1-flag_stack[0] #All Objects
  966.         flag_stack[1] = 1-flag_stack[1] #Selected Only
  967.         Blender.Draw.Redraw(1)
  968.  
  969.     if event == EVENT_SEL:
  970.         flag_stack[1] = 1-flag_stack[1] #Selected Only
  971.         flag_stack[0] = 1-flag_stack[0] #All Objects
  972.         Blender.Draw.Redraw(1)
  973.  
  974.     if event == EVENT_NOR:
  975.         flag_stack[2] = 1-flag_stack[2] #Vertex Normals
  976.         Blender.Draw.Redraw(1)
  977.  
  978.     if event == EVENT_COL:
  979.         flag_stack[3] = 1-flag_stack[3] #Vertex Colors
  980.         Blender.Draw.Redraw(1)
  981.  
  982.     if event == EVENT_CAM:
  983.         flag_stack[4] = 1-flag_stack[4] #Cameras
  984.         Blender.Draw.Redraw(1)
  985.  
  986.     if event == EVENT_LIG:
  987.         flag_stack[5] = 1-flag_stack[5] #Lights
  988.         Blender.Draw.Redraw(1)
  989.  
  990.     if event == EVENT_EXP:
  991.         tmp_filename = Blender.sys.makename(ext = ".b3d")
  992.         Blender.Window.FileSelector(savefile_callback,"Export B3D",tmp_filename)
  993.  
  994.     if event == EVENT_QUI:
  995.         Blender.Draw.Exit()
  996.  
  997. #Handle GUI
  998. def handle_event(event,value):
  999.     if event == Blender.Draw.ESCKEY:
  1000.         Blender.Draw.Exit()
  1001.         return
  1002.  
  1003. #Draw GUI
  1004. def draw_gui():
  1005.     global EVENT_ALL,EVENT_SEL
  1006.     global EVENT_NOR,EVENT_COL,EVENT_CAM,EVENT_LIG
  1007.     global EVENT_EXP,EVENT_QUI
  1008.     button_width = 222
  1009.     button_height = 20
  1010.  
  1011.     def draw_rect(x,y,width,height):
  1012.         glBegin(GL_LINE_LOOP)
  1013.         glVertex2i(x,y)
  1014.         glVertex2i(x+width,y)
  1015.         glVertex2i(x+width,y-height)
  1016.         glVertex2i(x,y-height)
  1017.         glEnd()
  1018.  
  1019.     Blender.BGL.glClearColor(34.0/255.0,85.0/255.0,136.0/255.0,1.0)
  1020.     Blender.BGL.glClear(Blender.BGL.GL_COLOR_BUFFER_BIT)
  1021.  
  1022.     glColor3f(170.0/255.0,255.0/255.0,255.0/255.0)
  1023.     draw_rect(20,330,262,310)
  1024.     draw_rect(22,328,258,306)
  1025.  
  1026.     glColor3f(255.0/255.0,238.0/255.0,0.0/255.0)
  1027.     glRasterPos2i(70,300)
  1028.     Draw.Text("Blitz3D Exporter 2.07",'large')
  1029.  
  1030.     Blender.Draw.Toggle("All Objects",EVENT_ALL,40,13*button_height,button_width,button_height,flag_stack[0],"Export All Scene Objects")
  1031.     Blender.Draw.Toggle("Selected Only",EVENT_SEL,40,12*button_height,button_width,button_height,flag_stack[1],"Export Only Selected Objects")
  1032.  
  1033.     Blender.Draw.Toggle("Normals",EVENT_NOR,40,10*button_height,button_width,button_height,flag_stack[2],"Export Vertex Normals")
  1034.     Blender.Draw.Toggle("Vertex Colors",EVENT_COL,40,9*button_height,button_width,button_height,flag_stack[3],"Export Vertex Colors")
  1035.     Blender.Draw.Toggle("Cameras",EVENT_CAM,40,8*button_height,button_width,button_height,flag_stack[4],"Export Cameras")
  1036.     Blender.Draw.Toggle("Lights",EVENT_LIG,40,7*button_height,button_width,button_height,flag_stack[5],"Export Lights")
  1037.  
  1038.     Blender.Draw.Button("Export",EVENT_EXP,40,5*button_height,button_width,button_height,"Export to B3D")
  1039.     Blender.Draw.Button("Quit",EVENT_QUI,40,4*button_height,button_width,button_height,"Quit this script")
  1040.  
  1041.     glRasterPos2i(36,55)
  1042.     Draw.Text("Copyright (C) 2009 by Diego 'GaNDaLDF' Parisi",'small')
  1043.     glRasterPos2i(105,37)
  1044.     Draw.Text("www.gandaldf.com",'small')
  1045.  
  1046. #Callback Functions
  1047. def savefile_callback(filename):
  1048.     if filename == "":
  1049.         return
  1050.  
  1051.     if not filename.endswith(".b3d"):
  1052.     filename += ".b3d"
  1053.  
  1054.     if Blender.sys.exists(filename):
  1055.     result = Draw.PupMenu("File Already Exists, Overwrite?%t|Yes%x1|No%x0")
  1056.     if result != 1:
  1057.         return
  1058.  
  1059.     start = Blender.sys.time()
  1060.     write_b3d_file(filename)
  1061.     end = Blender.sys.time()
  1062.     print "%s"%Blender.sys.basename(filename)+" successfully exported in %.4f seconds"%(end-start)
  1063.     Blender.Draw.Exit()
  1064.     return
  1065.  
  1066. #Export B3D
  1067. def export_b3d():
  1068.     flag_stack.append(1) #All Objects
  1069.     flag_stack.append(0) #Selected Only
  1070.     flag_stack.append(0) #Vertex Normals
  1071.     flag_stack.append(0) #Vertex Colors
  1072.     flag_stack.append(0) #Cameras
  1073.     flag_stack.append(0) #Lights
  1074.     draw_gui()
  1075.  
  1076. #Main
  1077. def main():
  1078.     export_b3d()
  1079.  
  1080. if __name__ == "__main__":
  1081.     Blender.Draw.Register(draw_gui,handle_event,handle_button)
  1082.     main()
  1083.  
Advertisement
Add Comment
Please, Sign In to add comment