Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on Mar 17th, 2011  |  syntax: Python  |  size: 23.60 KB  |  views: 95  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
This paste has a previous version, view the difference. Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #!BPY
  2.  
  3. #**************************************************************************************************
  4. # Supreme Commander Importer for Blender3D - www.blender3d.org
  5. #
  6. # Written by dan - www.sup-com.net
  7. # modified by Gniarf (2010/08)
  8. #
  9. # History
  10. #   0.1.0   06/06/06   - Initial version.
  11. #   0.2.0   06/06/10   - Added SCA (Animation) support
  12. #   0.3.0   06/07/02   - Alpha release
  13. #   0.4.0   10/08/12   - modification to load Supcom2 sca won't load Supcom 1 sca anymore
  14. #
  15. # Todo
  16. #   - Material/uv map 2
  17. #   - Bone pos/rot for scm & sca. Not perfect to use gentle words.
  18. #   - Make sca loading independent of the scm_mesh. (e.g get bone pos/loc from armature instead)
  19. #   - GUI for loading
  20. #
  21. #**************************************************************************************************
  22.  
  23. """
  24. Name: 'SupCom2 Model (.scm)'
  25. Blender: 232
  26. Group: 'Import'
  27. Tooltip: 'Imports Supreme Commander 2 Models (*.scm) and Animations (*.sca)'
  28. """
  29.  
  30. import Blender
  31. from Blender import NMesh, Scene, Object
  32.  
  33. from Blender import Mathutils
  34. from Blender.Mathutils import *
  35.  
  36. from Blender.BGL import *
  37. from Blender import Draw
  38. from Blender.Draw import *
  39.  
  40. import os
  41. from os import path
  42.  
  43.  
  44. import struct
  45. import string
  46. import math
  47. from math import *
  48.  
  49.  
  50. VERSION = '4.5'
  51.  
  52. ######################################################
  53. # User defined behaviour, Select as you need
  54. ######################################################
  55.  
  56. #Enable Progress Bar ( 0 = faster )
  57. PROG_BAR_ENABLE = 1
  58. #how many steps a progress bar has (the lesser the faster)
  59. PROG_BAR_STEP = 25
  60.  
  61. #LOG File for debuging
  62. #Enable LOG File (0 = Disabled , 1 = Enabled )
  63. LOG_ENABLE = 0
  64. #Filename / Path. Default is blender directory Filename SC-E_LOG.txt
  65. LOG_FILENAME = "SC-E_LOG.txt"
  66.  
  67. ######################################################
  68. # Init Supreme Commander SCM( _bone, _vertex, _mesh), SCA(_bone, _frame, _anim) Layout
  69. ######################################################
  70. #xy_to_xz_transform = Matrix([1, 0, 0], [ 0, 0, 1], [ 0, 1, 0])
  71. xy_to_xz_transform = Matrix([1, 0, 0], [ 0, 0, 1], [ 0, -1, 0])
  72.  
  73.  
  74.         #       -1      0       0
  75.         #       0       0       1
  76.         #       0       1       0
  77.  
  78.  
  79. class scm_bone :
  80.        
  81.         name = ""
  82.         rel_mat = []
  83.         rel_mat_inv = []
  84.         position = []
  85.         rotation = []
  86.         parent = 0
  87.         parent_index = 0
  88.        
  89.         rel_matrix_inv = []
  90.        
  91.         def __init__(self, name):
  92.                 self.name = name
  93.                 self.rel_mat_inv = Matrix([0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0])
  94.                 self.rel_mat = Matrix([0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0])
  95.                 self.rotation = Quaternion(0,0,0,0)
  96.                 self.position = Vector(0,0,0)
  97.  
  98.         def load(self, file):
  99.                 bonestruct = '16f3f4f4i'
  100.                 buffer = file.read(struct.calcsize(bonestruct))
  101.                 readout = struct.unpack(bonestruct, buffer)
  102.  
  103.                 #supcom information:
  104.                 readRPI = Matrix([0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0])
  105.                 #// Inverse transform of the bone relative to the local origin of the mesh
  106.                 #// 4x4 Matrix with row major (i.e. D3D default ordering)
  107.                 for i in range(4):
  108.                         readRPI[i] = readout[i*4:i*4+4]
  109.                
  110.                 self.rel_mat_inv = Matrix(readRPI[0], readRPI[1], readRPI[2], readRPI[3])#*xy_to_xz_transform #note rot here changes pointing direction of spikie
  111.                 self.rel_mat = self.rel_mat_inv.invert()
  112.  
  113.                 #self.rel_mat = (Matrix(rest_pose_inv).invert())
  114.  
  115.                 #// Position relative to the parent bone.
  116.                 pos = readout[16:19]
  117.                 self.position = Vector(pos[0], pos[1], pos[2])
  118.                
  119.                 #// Rotation relative to the parent bone.
  120.                 rot = readout[19:23]
  121.                 self.rotation = Quaternion( rot[0], rot[1], rot[2], rot[3] )
  122.  
  123.                 #// Index of the bone's parent in the SCM_BoneData array
  124.                 self.parent_index = readout[24]
  125.  
  126.                
  127.                 return self
  128.        
  129.         def dump(self):
  130.                 print 'Bone       ', self.name
  131.                 print 'Position   ', self.position
  132.                 print 'Rotation   ', self.rotation
  133.                 print 'Parent Idx ', self.parent_index         
  134.                 if (self.parent != 0):
  135.                         print 'Parent     ', self.parent.name
  136.                 else:
  137.                         print 'Parent     <NONE>'              
  138.                 print 'Rest Pose Inv.'
  139.                 #for row in range(4):
  140.                         #print '  ', self.rest_pose_inv[row]           
  141.  
  142.  
  143. class scm_vertex :
  144.        
  145.         position = []
  146.         tangent = []
  147.         normal = []
  148.         binormal = []
  149.         uv1 = []
  150.         uv2 = []
  151.         bone_index = []
  152.  
  153.         def __init__(self):
  154.                 self.position   = Vector(0,0,0)
  155.                 self.tangent    = Vector(0,0,0)
  156.                 self.normal     = Vector(0,0,0)
  157.                 self.binormal   = Vector(0,0,0)
  158.                 self.uv1        = Vector(0,0)
  159.                 self.uv2        = Vector(0,0)
  160.                 self.bone_index = [0]*4
  161.  
  162.         def load(self, file):
  163.                
  164.                 vertstruct = '3f3f3f3f2f2f4B'
  165.                 vertsize = struct.calcsize(vertstruct)
  166.                
  167.                
  168.                 buffer = file.read(vertsize)
  169.                 vertex = struct.unpack(vertstruct, buffer)
  170.                
  171.                 self.position = vertex[0:3]
  172.                 self.tangent = vertex[3:6]
  173.                 self.normal = vertex[6:9]
  174.                 self.binormal = vertex[9:12]
  175.                 self.uv1 = vertex[12:14]
  176.                 self.uv2 = vertex[14:16]
  177.                 self.bone_index = vertex[16:20]
  178.                 return self
  179.        
  180.         def dump(self):
  181.                 print 'position ', self.position
  182.                 print 'tangent  ', self.tangent
  183.                 print 'normal   ', self.normal
  184.                 print 'binormal ', self.binormal
  185.                 print 'uv1      ', self.uv1
  186.                 print 'uv2      ', self.uv2
  187.                 print 'bones    ', self.bone_index
  188.  
  189.  
  190. class scm_mesh :
  191.        
  192.         bones = []
  193.         vertices = []
  194.         faces = []
  195.         info = []
  196.         filename = ""
  197.        
  198.         def __init__(self):
  199.                 self.bones = []
  200.                 self.vertices = []
  201.                 self.faces = []
  202.                 self.info = []
  203.                 self.filename = ""
  204.  
  205.         def load(self, filename):      
  206.                 global xy_to_xz_transform
  207.                 self.filename = filename
  208.                 scm = file(filename, 'rb')
  209.                
  210.                 # Read header
  211.                 headerstruct = '4s11L'
  212.                 buffer = scm.read(struct.calcsize(headerstruct))
  213.                 header = struct.unpack(headerstruct, buffer)
  214.                
  215.                 marker = header[0]
  216.                 version = header[1]
  217.                 boneoffset = header[2]
  218.                 bonecount = header[3]
  219.                 vertoffset = header[4]
  220.                 extravertoffset = header[5]
  221.                 vertcount = header[6]
  222.                 indexoffset = header[7]
  223.                 indexcount = header[8]
  224.                 tricount = indexcount / 3 #?
  225.                 infooffset = header[9]
  226.                 infocount = header[10]
  227.                 totalbonecount = header[11]
  228.                
  229.                 if (marker != 'MODL'):
  230.                         print 'Not a valid scm'
  231.                         return
  232.                        
  233.                 #if (version != 5):
  234.                 #       print 'Unsupported version (%d)' % version
  235.                 #       return
  236.                
  237.                 # Read bone names
  238.                 scm.seek(pad(scm.tell()), 1)
  239.                 length = (boneoffset - 4) - scm.tell()
  240.  
  241.                 # This should probably be handeled by the scm_bone reader as it contains the nameoffset. But I'm lazy
  242.                 # and logic tells me it's written in the same order as the bones.
  243.                 buffer = scm.read(length)              
  244.                 rawnames = struct.unpack(str(length)+'s',buffer)               
  245.                 bonenames = string.split(rawnames[0],'\0')[:-1]
  246.                
  247.                 # Read bones
  248.                 scm.seek(boneoffset, 0)
  249.                 for b in range(0, totalbonecount):
  250.                         bone = scm_bone(bonenames[b])
  251.                         bone.load(scm)                 
  252.                         self.bones.append(bone)
  253.                                
  254.                 #show them (for debug)                         
  255.                 #for b in range(0, totalbonecount):
  256.                         #print "bone %d has %d children = " %(b, self.bones[b].numchildren)
  257.                
  258.                 # Set parent (this could probably be done in the other loop since parents are usually written to the file
  259.                 # before the children. But you never know..
  260.                 for bone in self.bones:
  261.                         if (bone.parent_index != -1):
  262.                                 bone.parent = self.bones[bone.parent_index]
  263.                         else:
  264.                                 bone.parent = 0
  265.                
  266.                         # the bone matrix relative to the parent.
  267.                         if (bone.parent != 0):
  268.                                 mrel = (bone.rel_mat) * Matrix(bone.parent.rel_mat).invert() #* xy_to_xz_transform
  269.                                 bone.rel_matrix_inv = Matrix(mrel).invert()
  270.                         else:
  271.                                 mrel = bone.rel_mat * xy_to_xz_transform  #there is no parent
  272.                                 bone.rel_matrix_inv = Matrix(mrel).invert()
  273.                                                
  274.                
  275.                 # Read vertices
  276.                 scm.seek(vertoffset, 0)
  277.                 for b in range(0, vertcount):
  278.                         vert = scm_vertex()
  279.                         vert.load(scm)                 
  280.                         self.vertices.append(vert)
  281.                
  282.                 # Read extra vertex data               
  283.                 # Not implemented in Sup Com 1.0!
  284.                
  285.                 # Read indices (triangles)
  286.                 tristruct = '3h'
  287.                 trisize = struct.calcsize(tristruct)
  288.                        
  289.                 scm.seek(indexoffset, 0)                       
  290.                 for t in range(tricount):                      
  291.                         buffer = scm.read(trisize)
  292.                         face = struct.unpack(tristruct, buffer)
  293.                         self.faces.append(list(face))
  294.                        
  295.                
  296.                 # Read info
  297.                 if (infocount > 0):
  298.                         scm.seek(infooffset)
  299.                         buffer = scm.read()
  300.                         rawinfo = struct.unpack(str(len(buffer))+'s',buffer)           
  301.                         self.info = string.split(rawinfo[0],'\0')[:-1]
  302.                
  303.                 scm.close()    
  304.                
  305.                 return self
  306.  
  307.         def dump(self):
  308.                 print ''
  309.                 print 'Filename: ', self.filename
  310.                 print 'Bones ', len(self.bones)
  311.                 print 'Verts ', len(self.vertices)
  312.                 print 'Faces ', len(self.faces)        
  313.                 print ''
  314.                 print 'INFO: '
  315.                 for info in self.info:
  316.                         print '  ', info
  317.                
  318.  
  319.  
  320. class sca_bone:
  321.  
  322.         position = []
  323.         rotation = []
  324.         #changed: rototation -> rotation
  325.         pose_pos = []
  326.         pose_rot = []
  327.  
  328.         def __init__(self, pos, rot):
  329.                 self.position = pos
  330.                 self.rotation = rot
  331.  
  332.  
  333.         def dump(self):
  334.                 print 'Position ', self.position
  335.                 print 'Rotation ', self.rotation
  336.                
  337.  
  338.  
  339. class sca_frame:
  340.  
  341.         keytime = 0.0
  342.         bones = []
  343.         anim = None
  344.        
  345.         def __init__(self, anim):
  346.                 self.keytime = 0.0
  347.                 self.bones = []
  348.                 self.anim = anim
  349.  
  350.         def load(self, file):          
  351.                 frameheader_fmt = 'f'
  352.                 frameheader_size = struct.calcsize(frameheader_fmt)
  353.                 buffer = file.read(frameheader_size)
  354.                
  355.                 (self.keytime,) = struct.unpack(frameheader_fmt, buffer)
  356.                
  357.                 posrot_fmt = '3f4f'
  358.                 posrot_size = struct.calcsize(posrot_fmt)
  359.                
  360.                 buffer = file.read(posrot_size)
  361.                 posrot = struct.unpack(posrot_fmt, buffer)                     
  362.                 bone = sca_bone([posrot[4],posrot[5],posrot[6]], [posrot[0],posrot[1],posrot[2],posrot[3]])
  363.                 self.bones.append(bone)
  364.  
  365.         def dump(self):
  366.                 print 'Time  ', self.keytime
  367.                
  368.  
  369.  
  370. class sca_anim :
  371.        
  372.         filename = ""
  373.         frames = [[]]
  374.         bones = []
  375.         bonelinks = []
  376.         bonenames = []
  377.         numbones = 0
  378.         duration = 0.0
  379.         numframes = 0
  380.        
  381.         def __init__(self):
  382.                 self.filename = ""
  383.                 self.frames=list()
  384.                 self.bones = []
  385.                 self.numbones = 0
  386.                 self.bonelinks = []
  387.                 self.bonenames = list()
  388.                 self.duration = 0.0
  389.  
  390.         def read_bone_name(self,sca):
  391.                 bone_name=""
  392.                 letter=""
  393.                 while letter!='\0':
  394.                         bone_name=bone_name+letter
  395.                         letter=sca.read(1)
  396.                 return bone_name
  397.  
  398.         def load(self, filename):
  399.                 self.filename = filename
  400.                 sca = file(filename, 'rb')
  401.                
  402.                 # Read header
  403.                 headerstruct = '4sllflllll'
  404.                 buffer = sca.read(struct.calcsize(headerstruct))
  405.                 header = struct.unpack(headerstruct, buffer)
  406.                
  407.                
  408.                 (magic,             \
  409.                  version,           \
  410.                  self.numframes,         \
  411.                  self.duration,     \
  412.                  self.numbones,     \
  413.                  namesoffset,       \
  414.                  linksoffset,       \
  415.                  animoffset,        \
  416.                  framesize) = struct.unpack(headerstruct, buffer)
  417.                  
  418.                 #namesoffset,linksoffset,animoffset are NOT always
  419.                 #reliable, so use data alignment instead
  420.                
  421.                 if (magic != 'ANIM'):
  422.                         print 'Not a valid .sca animation file'
  423.                         return
  424.                
  425.                 #if (version != 5):
  426.                 #       print 'Unsupported sca version: %d'  % version
  427.                 #       return
  428.                
  429.                 #Read bone names
  430.                 # go to next section (names)
  431.                 token_found=0
  432.                 while (token_found==0):
  433.                         sca.seek(28-(sca.tell()%32), os.SEEK_CUR )
  434.                         magic = sca.read(4)
  435.                         if (magic=='NAME'):
  436.                                 token_found=1
  437.                         else:
  438.                                 sca.seek(8, os.SEEK_CUR )
  439.                                
  440.                
  441.                 for i in range(0,self.numbones):
  442.                         self.bonenames.append(self.read_bone_name(sca))
  443.                         print self.bonenames[i]
  444.                
  445.                 # Read links
  446.                 token_found=0
  447.                 while (token_found==0):
  448.                         sca.seek(28-(sca.tell()%32), os.SEEK_CUR )
  449.                         magic = sca.read(4)
  450.                         if (magic=='LINK'):
  451.                                 token_found=1
  452.                         else:
  453.                                 sca.seek(8, os.SEEK_CUR )
  454.                 links_fmt = str(self.numbones)+'l'
  455.                 links_size = struct.calcsize(links_fmt)
  456.                 buffer = sca.read(links_size)
  457.                 self.bonelinks = struct.unpack(links_fmt, buffer)
  458.                        
  459.                 posrot_fmt = '3f4f'
  460.                 posrot_size = struct.calcsize(posrot_fmt)
  461.                
  462.                 # go to next section (data)
  463.                 #sounds like data is 0x40 aligned
  464.                 token_found=0
  465.                 while (token_found==0):
  466.                         sca.seek(28-(sca.tell()%32), os.SEEK_CUR )
  467.                         magic = sca.read(4)
  468.                         if (magic=='DATA'):
  469.                                 token_found=1
  470.                         else:
  471.                                 sca.seek(8, os.SEEK_CUR )
  472.                 buffer = sca.read(posrot_size)
  473.                 root_posrot = struct.unpack(posrot_fmt, buffer)
  474.                 for f in range(0, self.numbones) :
  475.                         buffer = sca.read(4)
  476.                         (frames_for_this_bone,) = struct.unpack('l', buffer)
  477.                         frame_list_for_this_bone=list()
  478.                         for i in range(0, frames_for_this_bone):
  479.                                 frame_list_for_this_bone.append(sca_frame(self))
  480.                                 frame_list_for_this_bone[i].load(sca)
  481.                         self.frames.append(frame_list_for_this_bone)
  482.                 sca.close()
  483.                
  484.                 return self
  485.  
  486.         def dump(self):
  487.                 print 'SCA:  ', self.filename
  488.                 print 'Duration: %fs' % self.duration
  489.                 print 'Num loaded frames ', len(self.frames)
  490.                
  491.                 print 'Bonelinks'              
  492.                 for link in self.bonelinks:
  493.                         print ' ', link
  494.                
  495.                 print 'Bone names'
  496.                 for name in self.bonenames:
  497.                         print ' ', name
  498.        
  499.                                
  500. def pad(size):
  501.         val = 32 - (size % 32)
  502.        
  503.         if (val > 31):
  504.                 return 0
  505.                
  506.         return val
  507.                        
  508.                        
  509. #**************************************************************************************************
  510. # Blender Interface
  511. #**************************************************************************************************
  512. def GetLeftRightBone(BoneNames,bone):
  513.         if BoneNames[bone].find("Left") != -1:
  514.                 return BoneNames[bone].replace("Left","Right",1)
  515.         elif BoneNames[bone].find("Right") != -1:
  516.                 return BoneNames[bone].replace("Right","Left",1)
  517.         return BoneNames[bone]
  518.  
  519.  
  520. def read_scm() :
  521.         global xy_to_xz_transform
  522.         global scm_filepath # [0] both [1] path [2] name
  523.         global sca_filepath # [0] both [1] path [2] name
  524.        
  525.         print "=== LOADING Sup Com Model ==="
  526.         print ""
  527.        
  528.         xy_to_xz_transform.resize4x4()
  529.        
  530.         scene = Blender.Scene.GetCurrent()      
  531.        
  532.         mesh = scm_mesh()
  533.        
  534.         if (mesh.load(scm_filepath[0]) == None):
  535.                 print 'Failed to load %s' %scm_filepath[2]
  536.                 return
  537.        
  538.         ProgBarLSCM = ProgressBar( "Imp: load SCM", (2*len(mesh.vertices) + len(mesh.faces)))  
  539.        
  540.         armature_name = string.rstrip(scm_filepath[2], ".scm")
  541.         print "armature ", armature_name
  542.        
  543.         ###             CREATE ARMATURE
  544.         armObj = Object.New('Armature', armature_name)  #bad
  545.        
  546.         armData = Blender.Armature.Armature(armature_name)
  547.         armData.drawAxes = True
  548.         armData.makeEditable() 
  549.          
  550.         for index in range(len(mesh.bones)):
  551.                 bone = mesh.bones[index]       
  552.                 blender_bone = Blender.Armature.Editbone()             
  553.                 #not nice parent may not exist,  but usualy should exist (depends on storing in scm)
  554.                 if (bone.parent != 0) :
  555.                         blender_bone.parent = armData.bones[bone.parent.name]
  556.                
  557.  
  558.                 #blender_bone.options(Armature.CONNECTED)
  559.                 blender_bone.matrix = Matrix(bone.rel_mat * xy_to_xz_transform)        
  560.                                
  561.                 armData.bones[bone.name] = blender_bone
  562.  
  563.        
  564.         #save changes (after linking!)
  565.         armObj.link(armData)
  566.         scene.link(armObj)
  567.         #scene.objects.new(armData)
  568.         ###             CREATE MESH
  569.         meshData = Blender.Mesh.New('Mesh')
  570.        
  571.         ProgBarLSCM.text = "IMP: Verticles"
  572.         #add verts
  573.         vertlist = []
  574.         for vert in mesh.vertices:
  575.                 ProgBarLSCM.do()
  576.                 vertlist.append(Vector(vert.position)*xy_to_xz_transform)
  577.        
  578.         meshData.verts.extend(vertlist)
  579.  
  580.         meshData.vertexUV = True
  581.         for i_v in xrange(len(meshData.verts)):
  582.                 uv1 = mesh.vertices[i_v].uv1
  583.                 meshData.verts[i_v].uvco = Vector(uv1[0], 1.0-uv1[1])
  584.        
  585.         ProgBarLSCM.text = "IMP: Faces"
  586.        
  587.         #reverse faces
  588.         #for face in mesh.faces:
  589.         #       face.reverse()
  590.                
  591.         #add faces
  592.         meshData.faces.extend(mesh.faces)      
  593.         meshData.faceUV = True 
  594.         for face in meshData.faces :
  595.                 ProgBarLSCM.do()
  596.                 face.uv = [face.verts[i].uvco for i in range(3)]
  597.        
  598.         #put in scene
  599.         mesh_obj = Object.New('Mesh','Mesh')
  600.         mesh_obj.link(meshData)
  601.        
  602.         #scene.objects.new(meshData)
  603.  
  604.         #assigns vertex groups #mesh must be in object
  605.         for bone in mesh.bones:
  606.                 meshData.addVertGroup(bone.name)
  607.  
  608.         for vertex_index in range(len(mesh.vertices)):
  609.                 ProgBarLSCM.do()
  610.                 vertex = mesh.vertices[vertex_index]
  611.                 bone_index = vertex.bone_index[0]
  612.                 meshData.assignVertsToGroup(mesh.bones[bone_index].name, [vertex_index], 1.0, Blender.Mesh.AssignModes.REPLACE) #'REPLACE'
  613.        
  614.         # it works... but you've to select/change to edit mode for the object to show up.
  615.         # dunno why that is, maybe because Nmesh is depracated.
  616.         meshData.update()
  617.                
  618.         #bones disapear wen update ?
  619.         #armData.update()
  620.  
  621.         scene.link(mesh_obj)
  622.        
  623.         #must be in scene
  624.         #armObj = None
  625.         #meshObj = None
  626.         #for obj in Object.Get():
  627.         #       if obj.getType() == 'Armature':
  628.         #               armObj = obj
  629.         #       if obj.getType() == 'Mesh':
  630.         #               meshObj = obj
  631.                        
  632.         #mesh_obj = Blender.Object.Get('Mesh')
  633.         armObj.makeParentDeform([mesh_obj], 0, 0)
  634.         #makeParentVertex(objects, indices, noninverse=0, fast=0)
  635.        
  636.         meshData.update()
  637.         armData.update()
  638.  
  639.         if len(mesh.info):
  640.                 print "=== INFO ==="
  641.                 for info in mesh.info:
  642.                         print "",info
  643.  
  644.         print "=== COMPLETE ==="
  645.        
  646.         if sca_filepath[0] != "" :
  647.                 read_anim(mesh)
  648.  
  649.        
  650.  
  651.  
  652. def read_anim(mesh):
  653.         global sca_filepath # [0] both [1] path [2] name
  654.  
  655.        
  656.         print "=== LOADING Sup Com Animation ==="
  657.         print ""
  658.        
  659.         anim = sca_anim()
  660.         anim.load(sca_filepath[0])
  661.        
  662.         ProgBarLSCA = ProgressBar( "Imp: Frames", len(anim.frames))
  663.        
  664.         scene = Blender.Scene.GetCurrent()
  665.        
  666.         arm_obj = None
  667.         for obj in scene.objects:
  668.                 data = obj.getData()
  669.                 if type(data) is Blender.Types.ArmatureType:
  670.                         arm_obj = obj
  671.                         break
  672.                
  673.         if arm_obj == None:
  674.                 print "couldn't apply animation, no armature in the scene"
  675.                 return
  676.  
  677.         print arm_obj.name
  678.        
  679.         action = Blender.Armature.NLA.NewAction(sca_filepath[2])
  680.         action.setActive(arm_obj)
  681.        
  682.         pose = arm_obj.getPose()
  683.        
  684.         for b in range(0,anim.numbones):
  685.                 ProgBarLSCA.do()
  686.                 for frame_index in range(0,len(anim.frames[b]) ):
  687.                        
  688.                         frame = anim.frames[b][frame_index]
  689.                         #Blender.Set("curframe",1+frame_index)
  690.                        
  691.                         pose_bone = pose.bones[anim.bonenames[b]]
  692.                        
  693.                         if (pose_bone == None):
  694.                                 print 'Frame %d - Bone \"%s\" not found' % (frame_index, anim.bonenames[b])
  695.                                 continue       
  696.  
  697.                         anim_bone = frame.bones[0]
  698.                         pose_bone.loc = Vector(anim_bone.position)-Vector(mesh.bones[b].position)
  699.                         pose_bone.quat = DifferenceQuats(Quaternion(mesh.bones[b].rotation), Quaternion(anim_bone.rotation))
  700.                         #switch x and -y
  701.                         temp=pose_bone.loc.x
  702.                         pose_bone.loc.x=pose_bone.loc.y
  703.                         pose_bone.loc.y=temp
  704.                         # print anim.bonenames[b]
  705.                         # print " loc x=" +str(pose_bone.loc.x) +" y="+str(pose_bone.loc.y)+" z="+str(pose_bone.loc.z)
  706.                         # print " rot x=" +str(pose_bone.quat.x) +" y="+str(pose_bone.quat.y)+" z="+str(pose_bone.quat.z)+" w="+str(pose_bone.quat.w)
  707.                        
  708.  
  709.  
  710.                         pose_bone.size = Vector(1,1,1)
  711.                                        
  712.                         pose.update()
  713.                         pose_bone.insertKey(arm_obj, 1+int(anim.numframes*frame.keytime/anim.duration), [Blender.Object.Pose.LOC, Blender.Object.Pose.ROT, Blender.Object.Pose.SIZE])
  714.                         pose.update()
  715.        
  716.        
  717.         Blender.Set("curframe", 1)
  718.        
  719.         #scene = Blender.Scene.GetCurrent()
  720.         context = scene.getRenderingContext()
  721.  
  722.         context.endFrame(anim.numframes)
  723.        
  724.         print "=== COMPLETE ==="
  725.  
  726.  
  727.  
  728. ######################################################
  729. # GUI
  730. ######################################################
  731.        
  732. log = []
  733. log_max_lines = 14
  734. LOG_FILE = None
  735.  
  736. #log to file
  737. def LOGn(message):
  738.         global LOG_FILE
  739.         global LOG_ENABLE
  740.         global LOG_FILENAME
  741.        
  742.         if LOG_ENABLE :
  743.                 if LOG_FILE == None :                  
  744.                         LOG_FILE = open( LOG_FILENAME, 'w')
  745.                         LOG_FILE.write('SupCom Exporter LOG File:\n\n')
  746.                        
  747.                         LOGp( "LOG enabled: %s" % (LOG_FILENAME))
  748.                         Log(message + '\n')
  749.                        
  750.                 else :         
  751.                         LOG_FILE.write(message + '\n')
  752.                        
  753. #Log to file, to console and exp window                                
  754. def LOGp(message):
  755.         global log, log_max_lines
  756.        
  757.         LOGn(message)
  758.         print message  
  759.         log.append(message)
  760.        
  761.         if len(log) > log_max_lines:
  762.                 del log[0]
  763.                
  764.                
  765. counter = []
  766. cLog = []
  767. #log for a amount of errors like vertex errors
  768. def countLOG(message):
  769.         global cLog
  770.         global counter
  771.        
  772.         cont = False
  773.        
  774.         for i in xrange(len(cLog)):
  775.                 if cLog[i] == message:
  776.                         cont = True
  777.                         counter[i] +=1
  778.                         break
  779.                        
  780.         if not cont :
  781.                
  782.                 cLog.append( message)
  783.                 counter.append( 1)
  784.  
  785. def closeLog():
  786.         global cLog, LOG_FILE
  787.         global counter
  788.        
  789.         for i in xrange(len(cLog)):
  790.                 LOGp("%s (Times:%d)" % (cLog[i], counter[i]))
  791.  
  792.         if LOG_FILE != None :
  793.                 LOG_FILE.close()       
  794.                
  795.         Blender.Window.RedrawAll()
  796.                
  797.  
  798. class ProgressBar :
  799.  
  800.         global PROG_BAR_STEP
  801.         global PROG_BAR_ENABLE
  802.        
  803.         progress = 0
  804.         progressold = 0
  805.         current = 0    
  806.         end = 0
  807.         div = 0
  808.         text = "None"  
  809.        
  810.         def __init__(self, text, end):
  811.                 self.progress = 0
  812.                 self.progressold = 0
  813.                 self.current = 0
  814.                 self.end = end
  815.                 self.text = text
  816.                 self.div = PROG_BAR_STEP
  817.                
  818.                 #it looks like blender needs to init this progress bar with 0.0
  819.                 if PROG_BAR_ENABLE :
  820.                         Blender.Window.DrawProgressBar ( 0.0 , text)
  821.                
  822.         def do(self):  
  823.                
  824.                 if PROG_BAR_ENABLE :
  825.                         self.current += 1
  826.                         self.progress = (self.current*self.div)/self.end
  827.                        
  828.                         if self.progress != self.progressold :
  829.                                 self.progressold = self.progress
  830.                                 Blender.Window.DrawProgressBar ( float(self.progress)/self.div , self.text)
  831.                                
  832.  
  833.  
  834.  
  835. # Events
  836. EVENT_DRAW = 1
  837. EVENT_EXIT = 2
  838. EVENT_SCMDIR = 3
  839. EVENT_SCADIR = 4
  840.  
  841.  
  842. show_log = 0
  843.  
  844. sca_filepath = [ "", "", "None"]
  845. scm_filepath = [ "", "", "None"]
  846.  
  847. def anim_fileselector_callback(filename):
  848.         global sca_filepath
  849.        
  850.         sca_filepath[0] = filename
  851.        
  852.         #print "Filename%sI\n" % filename
  853.         #if ( filename != "" ) :
  854.                 #sca_filepath = [ "" , "None"]
  855.                 #return
  856.         #else :
  857.        
  858.         length = len(filename)
  859.         if filename[length-4:length] == ".sca" :               
  860.                 sca_filepath[1], sca_filepath[2]  = os.path.split(filename)
  861.         else :
  862.                 sca_filepath[0] = ""
  863.                 sca_filepath[1] = ""
  864.                 sca_filepath[2] = "Non Supported"
  865.  
  866.  
  867. def fileselector_callback(filename):
  868.         global scm_filepath
  869.         #sadly you cant check whether the cancel button is pressed
  870.         scm_filepath[0] = filename
  871.         length = len(filename)
  872.         if filename[length-4:length] == ".scm" :               
  873.                 scm_filepath[1], scm_filepath[2]  = os.path.split(filename)
  874.         else :
  875.                 scm_filepath[0] = ""
  876.                 scm_filepath[1] = ""
  877.                 scm_filepath[2] = "Non Supported"
  878.  
  879.        
  880. def draw():
  881.         global EVENT_DRAW, EVENT_EXIT,EVENT_SCADIR,EVENT_SCADIR
  882.         global scm_filepath, sca_filepath, show_log
  883.         global log_max_lines, log
  884.         global VERSION
  885.  
  886.         # Titles
  887.         glClear(GL_COLOR_BUFFER_BIT)
  888.        
  889.         top = 60 + log_max_lines * 12 + 8
  890.         #top = 500
  891.         top_x = 304
  892.        
  893.         glColor3f(0.8, 0.8, 1)
  894.         glRecti(top_x, top, 4, 4)
  895.         glBegin(GL_LINES)
  896.         glColor3f(0.8, 0.8, 0.8)
  897.         glVertex2d(4, top)
  898.         glVertex2d(4, 4)
  899.         glVertex2d(4, 4)
  900.         glVertex2d(top_x, 4)
  901.         glColor3f(0.5, 0.5, 0.5)
  902.         glVertex2d(top_x, top)
  903.         glVertex2d(4, top)
  904.         glVertex2d(top_x, top)
  905.         glVertex2d(top_x, top-1)
  906.         glEnd()
  907.        
  908.         glColor3f(0, 0, 0)
  909.         glRasterPos2d(10, top-16)
  910.         Text("Supreme Commander2 Importer " + VERSION) 
  911.  
  912.         # Show exporting log
  913.         if show_log:
  914.  
  915.                 for index in range(0, len(log)):
  916.                         i = (len(log) - 1) - index
  917.                         glRasterPos2i(10, 40 + i*12)
  918.                         Text(log[index]) #, 'tiny')
  919.                
  920.                
  921.                 Button("Close", EVENT_EXIT , 10, 10, 80, 18)
  922.  
  923.                 # Exporter GUI
  924.         else:
  925.                
  926.                 Blender.Draw.Button("Browse SCM", EVENT_SCMDIR, 10, 45, 80, 18, "Select scm")
  927.                 Blender.Draw.Button("Browse SCA", EVENT_SCADIR, 10, 80, 80, 18, "Select sca")  
  928.                
  929.                 glRasterPos2d(100, 47)
  930.                 if scm_filepath[0] == "" :
  931.                         Text("SCM: " + scm_filepath[2])
  932.                 else:
  933.                         Text(":" + scm_filepath[2])
  934.                        
  935.                 glRasterPos2d(100, 82)
  936.                 if sca_filepath[0] == "" :
  937.                         Text("SCA: " + sca_filepath[2])
  938.                 else :
  939.                         Text(":" + sca_filepath[2])
  940.  
  941.                 # Draw and Exit Buttons
  942.                 Button("Import", EVENT_DRAW , 10, 10, 80, 18)
  943.                 Button("Exit", EVENT_EXIT , 100, 10, 80, 18)
  944.  
  945. def event(evt, val):   
  946.         if (evt == QKEY and not val):
  947.                 Exit()
  948.  
  949. def bevent(evt):
  950.         global EVENT_DRAW,EVENT_EXIT
  951.         global scm_filepath
  952.         global show_log
  953.  
  954.         if (evt == EVENT_EXIT):
  955.                 #show_log = 1
  956.                 Exit()
  957.        
  958.         elif (evt == EVENT_SCMDIR):
  959.                 Blender.Window.FileSelector (fileselector_callback, "Select SCM File")
  960.                 Blender.Redraw()
  961.                
  962.         elif (evt == EVENT_SCADIR):
  963.                 if scm_filepath[0] != "" :                     
  964.                         Blender.Window.FileSelector (anim_fileselector_callback, "Select SCA File", scm_filepath[1]+"\\")                      
  965.                 else :
  966.                         Blender.Window.FileSelector (anim_fileselector_callback, "Select SCA File")                    
  967.                 Blender.Redraw()
  968.        
  969.         elif (evt == EVENT_DRAW):
  970.                
  971.                 if (scm_filepath[0] != ''):            
  972.                         show_log = 1                   
  973.                         read_scm()
  974.                
  975.                 Blender.Redraw()
  976.  
  977.                
  978.  
  979. Register(draw, event, bevent)
  980.  
  981. #open fileselector automaticly
  982. Blender.Window.FileSelector (fileselector_callback, "Select SCM File")
clone this paste RAW Paste Data