Skip to content
Snippets Groups Projects
io_import_scene_unreal_psk.py 39.8 KiB
Newer Older
# ##### BEGIN GPL LICENSE BLOCK #####
#  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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####

bl_info = {
    "name": "Import Unreal Skeleton Mesh (.psk)",
    "author": "Darknet",
John Phan's avatar
John Phan committed
    "version": (2, 1),
    "location": "File > Import > Skeleton Mesh (.psk)",
    "description": "Import Skeleleton Mesh",
    "warning": "",
Luca Bonavita's avatar
Luca Bonavita committed
    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"
Luca Bonavita's avatar
Luca Bonavita committed
        "Scripts/Import-Export/Unreal_psk_psa",
Luca Bonavita's avatar
Luca Bonavita committed
    "tracker_url": "https://projects.blender.org/tracker/index.php?"\
        "func=detail&aid=21366",
Luca Bonavita's avatar
Luca Bonavita committed
    "category": "Import-Export"}
"""
Version': '2.0' ported by Darknet

Unreal Tournament PSK file to Blender mesh converter V1.0
John Phan's avatar
John Phan committed
Author: 
-Darknet (Redesign and reworked)
-D.M. Sturgeon (camg188 at the elYsium forum)
-#2011-01-20 MARIUSZ SZKARADEK GLOGOW POLAND 

Imports a *psk file to a new mesh

-No UV Texutre
-No Weight
-No Armature Bones
-No Material ID
"""

John Phan's avatar
John Phan committed
import bmesh
import mathutils
import math
from string import *
from struct import *
John Phan's avatar
John Phan committed
import struct
John Phan's avatar
John Phan committed
from bpy.props import *
John Phan's avatar
John Phan committed
from bpy_extras.io_utils import unpack_list, unpack_face_list

Quaternion = mathutils.Quaternion
John Phan's avatar
John Phan committed
bpy.types.Scene.unrealbonesize = FloatProperty(
    name="Bone Length",
    description="Bone Length from head to tail distance",
John Phan's avatar
John Phan committed
    default=1,min=0.001,max=1000)

#output log in to txt file
DEBUGLOG = False

scale = 1.0
bonesize = 1.0
John Phan's avatar
John Phan committed
skala = 1
flipyz = False   
flipuv = True

"""
def unpack_list(list_of_tuples):
    l = []
    for t in list_of_tuples:
        l.extend(t)
    return l
"""	
John Phan's avatar
John Phan committed
#pack read words	
def word(long): 
   s=''
   for j in range(0,long): 
       lit =  struct.unpack('c',plik.read(1))[0]
       #print(">",lit)
       #print(">",bytes.decode(lit))
       if ord(lit)!=0:
           #print(lit)
           s+=bytes.decode(lit)
           if len(s)>100:
               break
   return s
#pack read data   
def b(n):
    return struct.unpack(n*'b', plik.read(n))
def B(n):
    return struct.unpack(n*'B', plik.read(n))
def h(n):
    return struct.unpack(n*'h', plik.read(n*2))
def H(n):
    return struct.unpack(n*'H', plik.read(n*2))
def i(n):
    return struct.unpack(n*'i', plik.read(n*4))
def f(n):
    return struct.unpack(n*'f', plik.read(n*4))

#work in progress
#bmesh
#tess function prefix
def drawmesh():
    global DEBUGLOG, plik,vertexes,uvcoord,faceslist,num_faces,facemat,facesmooth,m
    global vertexes_ids,bonesdata,meshesdata,groups,num_materials,skala,flipyz,flipuv,mat_faceslist
    global vertices,faces
    print(faces[0])
    print("[CREATING MESH:]")
    me_ob = bpy.data.meshes.new('testmesh')
    #create mesh
    print("-Vertices count:",len(vertices))
    me_ob.vertices.add(len(vertices))
    print("-Faces count:",len(faces))
    me_ob.tessfaces.add(len(faces))
    print("-Creating vertices points...")
    me_ob.vertices.foreach_set("co", unpack_list(vertices))
    print("-Creating faces idx...")
    me_ob.tessfaces.foreach_set("vertices_raw",unpack_list( faces))
    for face in me_ob.tessfaces:
        print(dir(face))
        face.use_smooth = facesmooth[face.index]
        #face.material_index = facemat[face.index]#not yet working
    print("-Creating UV Texture...")
    me_ob.tessface_uv_textures.new('uvtexture')
    #uvtex = me_ob.tessface_uv_textures[0]
    for uv in me_ob.tessface_uv_textures:
        for face in me_ob.tessfaces:
            #uv.data[face.index].uv1.x = 
            
            #print(uv.data[face.index].uv1)
            #uv.data[face.index].uv1 = Vector(uvcoord[faces[face.index]][0],uvcoord[face.index][1])
            print(face.vertices_raw[0],face.vertices_raw[1],face.vertices_raw[2])
            uv.data[face.index].uv1 = mathutils.Vector((uvcoord[face.vertices_raw[0]][0],uvcoord[face.vertices_raw[0]][1]))
            uv.data[face.index].uv2 = mathutils.Vector((uvcoord[face.vertices_raw[1]][0],uvcoord[face.vertices_raw[1]][1]))
            uv.data[face.index].uv3 = mathutils.Vector((uvcoord[face.vertices_raw[2]][0],uvcoord[face.vertices_raw[2]][1]))

    ob = bpy.data.objects.new("TestObject",me_ob)
    #create vertex group
    for bone_id in range(len(bonesdata)):
        bonedata = bonesdata[str(bone_id)]
        namebone = bonedata[0]#.strip()[-25:]
        #print("NAME:",namebone)
        ob.vertex_groups.new(namebone)
    me_ob.update()
    bpy.context.scene.objects.link(ob) 
def drawmesh4():
    global DEBUGLOG, plik,vertexes,uvcoord,faceslist,num_faces,facemat,facesmooth,m
    global vertexes_ids,bonesdata,meshesdata,groups,num_materials,skala,flipyz,flipuv,mat_faceslist
    global vertices,faces
    print("CREATING MESH")
    me_ob = bpy.data.meshes.new('testmesh')
    print("CREATING BMESH")
    bm = bmesh.new()   # create an empty BMesh    
    #print(dir(bm))
    bm.from_mesh(me_ob)   # fill it in from a Mesh
        
    #print("CREATING:")
    
    #vertices
    #print("-VERTICES")
    #for v_co in vertices:
        #bm.verts.new(v_co)
    
    #faces
    #print("-FACES")
    for f_idx in faces:
        #face idx
        bm.faces.new([bm.verts[i] for i in f_idx])
    
    print("-FACE SMOOTHS")
    for face in bm.faces:
        face.smooth = facesmooth[face.index]    
    
    bm.to_mesh(me_ob) #write mesh
    ob = bpy.data.objects.new("TestObject",me_ob) 
    me_ob.update() #update object
    bpy.context.scene.objects.link(ob) #link to scene
    
    #print(dir(bm))
    
    #create vertex group
    for bone_id in range(len(bonesdata)):
        bonedata = bonesdata[str(bone_id)]
        namebone = bonedata[0]#.strip()[-25:]
        #print("NAME:",namebone)
        ob.vertex_groups.new(namebone)
        
    #print("CREATING > Assign Weights")
    
    
    materialname = "pskmat"
    psktexname = "psktex"
    
    me_ob.uv_textures.new()
    for matcount in range(1):
        matdata = bpy.data.materials.new(materialname + str(1))
        me_ob.materials.append(matdata)
    
    
    print(dir(me_ob))
    #me_ob.tessface_uv_textures.new(name=psktexname)
    #me_ob.uv_textures.new(name=psktexname)
    #me_ob.uv_textures[0].active =True
    
    #print((me_ob.uv_textures[0].name))
    #print(dir(me_ob.uv_textures[0]))
    #for uv in me_ob.uv_textures:
        #print(dir(uv.data[0]))
        
    """
    print("NEW TEXTURE")
    me_ob.uv_textures.new()
    
    print("CREATING UV")
    for uv in me_ob.uv_textures:
        #print(len(uv.data))
        for face in bm.faces:
            print(dir(face.verts[0]))
            #print(dir(uv.data[face.index].image))
            #print(dir(uv.data[face.index]))
    
    print("CREATING > Vertex Group")
    """
    bpy.context.scene.update()
def drawmesh3():
    global DEBUGLOG, plik,vertexes,uvcoord,faceslist,num_faces,facemat,facesmooth,m
    global vertexes_ids,bonesdata,meshesdata,groups,num_materials,skala,flipyz,flipuv,mat_faceslist
    global vertices,faces
    print("CREATING MESH")
    me_ob = bpy.data.meshes.new('testmesh')
    print("CREATING BMESH")
    bm = bmesh.new()   # create an empty BMesh    
    #print(dir(bm))
    bm.from_mesh(me_ob)   # fill it in from a Mesh
        
    print("CREATING:")
    
    #vertices
    print("-VERTICES")
    for v_co in vertices:
        bm.verts.new(v_co)
    
    #faces
    print("-FACES")
    for f_idx in faces:
        #face idx
        bm.faces.new([bm.verts[i] for i in f_idx])
    
    print("-FACE SMOOTHS")
    for face in bm.faces:
        face.smooth = facesmooth[face.index]    
    
    bm.to_mesh(me_ob) #write mesh
    ob = bpy.data.objects.new("TestObject",me_ob) 
    me_ob.update() #update object
    bpy.context.scene.objects.link(ob) #link to scene
    
    #print(dir(bm))
    
    #create vertex group
    for bone_id in range(len(bonesdata)):
        bonedata = bonesdata[str(bone_id)]
        namebone = bonedata[0]#.strip()[-25:]
        #print("NAME:",namebone)
        ob.vertex_groups.new(namebone)
        
    #print("CREATING > Assign Weights")
    
    
    materialname = "pskmat"
    psktexname = "psktex"
    
    me_ob.uv_textures.new()
    for matcount in range(1):
        matdata = bpy.data.materials.new(materialname + str(1))
        me_ob.materials.append(matdata)
    
    
    print(dir(me_ob))
    me_ob.tessface_uv_textures.new(name=psktexname)
    #me_ob.uv_textures.new(name=psktexname)
    #me_ob.uv_textures[0].active =True
    
    #print((me_ob.uv_textures[0].name))
    #print(dir(me_ob.uv_textures[0]))
    #for uv in me_ob.uv_textures:
        #print(dir(uv.data[0]))
        
    """
    print("NEW TEXTURE")
    me_ob.uv_textures.new()
    
    print("CREATING UV")
    for uv in me_ob.uv_textures:
        #print(len(uv.data))
        for face in bm.faces:
            print(dir(face.verts[0]))
            #print(dir(uv.data[face.index].image))
            #print(dir(uv.data[face.index]))
    
    print("CREATING > Vertex Group")
    """
    bpy.context.scene.update()    
def drawmesh1():
    global DEBUGLOG, plik,vertexes,uvcoord,faceslist,num_faces,facemat,facesmooth,m
    global vertexes_ids,bonesdata,meshesdata,groups,num_materials,skala,flipyz,flipuv,mat_faceslist
    global vertices,faces
    print(faces[0])
    me_ob = bpy.data.meshes.new('testmesh')
    #obmesh = bpy.data.objects.new('testdata',me_ob)
    #uvtex = me_ob.uv_textures.new(name="pskuvtexture")
    #uvtex = me_ob.tessface_uv_textures.new(name="pskuvtexture")
    
    #material = bpy.data.materials.new('pskmat')
    #me_ob.materials.append(material)
    #uvtex = me_ob.uv_textures.new('pskuvtexture')
    
    #create mesh
    #me_ob.from_pydata(vertexes,[],faceslist)#create the faces and vertices
	
    me_ob.vertices.add(len(vertices))
    me_ob.tessfaces.add(len(faces))
    me_ob.vertices.foreach_set("co", unpack_list(vertices))
    me_ob.tessfaces.foreach_set("vertices_raw",unpack_list( faces))
    
    
    
    #bm = bmesh.new()   # create an empty BMesh    
    #print(dir(bm))
    #bm.from_mesh(me_ob)   # fill it in from a Mesh
    
    
    #for v_co in vertices:
        #bm.verts.new(v_co)
    #for f_idx in faces:
        #bm.faces.new([bm.verts[i] for i in f_idx])
    
    
    #bm.to_mesh(me_ob)
    ob = bpy.data.objects.new("TestObject",me_ob)
    me_ob.update()
    bpy.context.scene.objects.link(ob) 
    
    #set face smooth list boolean
    #for face in bm.faces:
        #face.smooth = facesmooth[face.index]
    #bm.uv_textures.new()
    #print(dir(bm))
    #bm.verts.foreach_set("co", vertices)
    #bm.faces.add(len(faces))
    #bm.faces.foreach_set("vertices_raw", faces)
    
    #print(dir(me_ob))
    #print(dir(bm))
    
    #print(dir(uvtex.data[0].image))
    #for countm in range(len(me_ob.uv_textures)):
        #me_ob.update()
        #uvtex = me_ob.uv_textures[countm] #add one uv texture
        #me_ob.update()
        #for i, face in enumerate(bm.faces):
            #print(dir(face))
        
        
        
        
    #texture
    #texture = bpy.data.textures.new(name="texture",type='IMAGE')
    #material
    #matdata = bpy.data.materials.new(name="pskmat")
    #mtex = matdata.texture_slots.add()
    #mtex.texture = texture
    #mtex.texture_coords = 'UV'
    #mtex.use_map_color_diffuse = True
    #mtex.use_map_alpha = True
    #uvtex = me_ob.uv_textures[0]
    
    #print(dir(uvtex.data[0]))
    #print(dir(uvtex.data[0].image))
    #print(dir(texture))
    
    #for i, face in enumerate(bm.faces):
        #print(face.material_index)
        #face.material_index = faceuv[i][1]
        #blender_tface = uvtex.data[i].image #face
    """
    
    #mesh vertex group #not done
	#create vertex group
    for bone_id in range(len(bonesdata)):
       bonedata = bonesdata[str(bone_id)]
       namebone = bonedata[0]#.strip()[-25:]
       obmesh.vertex_groups.new(namebone)
    #assgin group
    for m in range(len(groups)):
            data = groups[m]
            w = float(data[0])
            v_id = data[1]
            gr = data[2]
            gr = bonenames[gr]
    
    #for vgroup in obmesh.vertex_groups:
        #print(vgroup.name,":",vgroup.index)
    
        for vgp in RWghts:
            #bone index
            if vgp[1] == vgroup.index:
                #print(vgp)
                #[vertex id],weight
                vgroup.add([vgp[0]], vgp[2], 'ADD')
    """
    
    
    # Finish up, write the bmesh back to the mesh
    #bm.to_mesh(me_ob)
    
    
    
    #print((uvtex.name))
    #print((uvtex.data))
    #print(dir(uvtex))
    #print(dir(uvtex.data[0].image))
    #print(type(uvtex.data[0].image))
    
    
    
    #bpy.context.scene.objects.link(obmesh)    
    bpy.context.scene.update()	
John Phan's avatar
John Phan committed
#Create Armature
def check_armature():
    global DEBUGLOG, plik,vertexes,uvcoord,faceslist,num_faces,facemat,facesmooth,m
    global vertexes_ids,bonesdata,meshesdata,groups,num_materials,skala,flipyz,flipuv,amt
    
    #create Armature
    bpy.ops.object.mode_set(mode='OBJECT')
    for i in bpy.context.scene.objects: i.select = False #deselect all objects

    bpy.ops.object.add(
     type='ARMATURE', 
     enter_editmode=True,
     location=(0,0,0))
    ob = bpy.context.object
    ob.show_x_ray = True
    ob.name = "ARM"
    amt = ob.data
    amt.name = 'Amt'
    amt.show_axes = True
    bpy.ops.object.mode_set(mode='EDIT')
    bpy.context.scene.update()
#Create bones
def make_bone():    
    global DEBUGLOG, plik,vertexes,uvcoord,faceslist,num_faces,facemat,facesmooth,m
    global vertexes_ids,bonesdata,meshesdata,groups,num_materials,skala,flipyz,flipuv,amt
    global bonenames
    bonenames = []
    
    print ('make bone')
    
    for bone_id in range(len(bonesdata)):
       bonedata = bonesdata[str(bone_id)]
       namebone = bonedata[0]#.strip()[-25:]
       newbone = amt.edit_bones.new(namebone)
       #those are need to show in the scene
       newbone.head = (0,0,0)
       newbone.tail = (0,0,1)
       bonenames.append(namebone)
    bpy.context.scene.update()
#Make bone parent
def make_bone_parent():    
    global DEBUGLOG, plik,vertexes,uvcoord,faceslist,num_faces,facemat,facesmooth,m
    global vertexes_ids,bonesdata,meshesdata,groups,num_materials,skala,flipyz,flipuv,amt    
    global children
    children = {}
    
    print ('make bone parent')
    for bone_id in range(len(bonesdata)):
        bonedata = bonesdata[str(bone_id)]
        namebone  = bonenames[bone_id]
        nameparent = bonenames[bonedata[1][2]]
        #print(nameparent)
        if nameparent != None:#make sure it has name
           parentbone = amt.edit_bones[nameparent]
           bonecurrnet = amt.edit_bones[namebone]
           bonecurrnet.parent = parentbone
    bpy.context.scene.update()
John Phan's avatar
John Phan committed
#make bone martix set    
def bones_matrix():    
    global DEBUGLOG, plik,vertexes,uvcoord,faceslist,num_faces,facemat,facesmooth,m
    global vertexes_ids,bonesdata,meshesdata,groups,num_materials,skala,flipyz,flipuv,amt
    
    for bone_id in range(len(bonesdata)):
        bonedata = bonesdata[str(bone_id)]
        namebone = bonedata[0]#.strip()[-25:]
        nameparent = bonenames[bonedata[1][2]]
        pos = bonedata[2][4:7] 
        rot = bonedata[2][0:4] 
        qx,qy,qz,qw = rot[0],rot[1],rot[2],rot[3]
        #print("Quaternion:",qx,qy,qz,qw)
        if bone_id==0:
            rot =  mathutils.Quaternion((qw,-qx,-qy,-qz))
        if bone_id!=0:
            rot =  mathutils.Quaternion((qw,qx,qy,qz))
        matrix = mathutils.Matrix()
        rot = rot.to_matrix().inverted()
        #print(rot)
        matrix[0][:3] = rot[0]
        matrix[1][:3] = rot[1]
        matrix[2][:3] = rot[2]
        matrix[3][:3] = pos
        if bone_id>0:
            bonedata.append(matrix*bonesdata[str(bonedata[1][2])][3])
        else:
            bonedata.append(matrix)
    bpy.context.scene.update()

#not working    
def make_bone_position():
    print ('make bone position')
    bpy.ops.object.mode_set(mode='EDIT')
    for bone_id in range(len(bonesdata)):
        bonedata = bonesdata[str(bone_id)]
        namebone = bonedata[0]#.strip()[-25:]
        bone = amt.edit_bones[namebone]
        bone.transform(bonedata[3], scale=True, roll=True)
        bvec = bone.tail- bone.head
        bvec.normalize()
        bone.tail = bone.head + 0.1 * bvec
        #bone.tail = bone.head + 1 * bvec
    bpy.context.scene.update()    
        
#not working  
def make_bone_position1():    
    print ('make bone position')
    bpy.ops.object.mode_set(mode='EDIT')
    for bone_id in range(len(bonesdata)):
        bonedata = bonesdata[str(bone_id)]
        namebone = bonedata[0]#.strip()[-25:]
        pos = bonedata[2][4:7] 
        pos1 = pos[0]*skala  
        pos2 = pos[1]*skala  
        pos3 = pos[2]*skala 
        if flipyz == False:
            pos = [pos1,pos2,pos3]
        if flipyz == True:
            pos = [pos1,-pos3,pos2]
        rot = bonedata[2][0:4] 
        qx,qy,qz,qw = rot[0],rot[1],rot[2],rot[3]
        if bone_id==0:
            rot = mathutils.Quaternion((qw,-qx,-qy,-qz))
        if bone_id!=0:
            rot = mathutils.Quaternion((qw,qx,qy,qz))
        #rot = rot.toMatrix().invert() 	
        rot = rot.to_matrix().inverted() 	
        bone = amt.edit_bones[namebone]
        #print("BONES:",amt.bones[0])
Luca Bonavita's avatar
Luca Bonavita committed
        
John Phan's avatar
John Phan committed
        if bone_id!=0:
            bone.head = bone.parent.head+mathutils.Vector(pos) * bone.parent.matrix
            #print(dir(rot))
            #print("rot:",rot)
            #print("matrix:",bone.parent.matrix)
            
            tempM = rot.to_4x4()*bone.parent.matrix
            #bone.matrix = tempM
            bone.transform(tempM, scale=False, roll=True)
            #bone.matrix_local = tempM
        else:
            bone.head = mathutils.Vector(pos)
            #bone.matrix = rot
            bone.transform(rot, scale=False, roll=True)
            #bone.matrix_local = rot
        bvec = bone.tail- bone.head
        bvec.normalize()
        bone.tail = bone.head + 0.1 * bvec
        #bone.tail = bone.head + 1 * bvec
    

Luca Bonavita's avatar
Luca Bonavita committed
#http://www.blender.org/forum/viewtopic.php?t=13340&sid=8b17d5de07b17960021bbd72cac0495f            
Luca Bonavita's avatar
Luca Bonavita committed
    v = (b.tail-b.head)/b.length
    b.roll -= math.degrees(math.atan2(v[0]*v[2]*(1 - v[1]),v[0]*v[0] + v[1]*v[2]*v[2])) 
Luca Bonavita's avatar
Luca Bonavita committed
    v = (b.tail-b.head)/b.length
    if v[2]*v[2] > .5:
        #align X-axis
        b.roll += math.degrees(math.atan2(v[0]*v[2]*(1 - v[1]),v[2]*v[2] + v[1]*v[0]*v[0]))
    else:
        #align Z-axis
        b.roll -= math.degrees(math.atan2(v[0]*v[2]*(1 - v[1]),v[0]*v[0] + v[1]*v[2]*v[2])) 
John Phan's avatar
John Phan committed
""" #did not port this yet unstable but work in some ways
def make_bone_position3():    
            for bone in md5_bones:
                #print(dir(bone))
                bpy.ops.object.mode_set(mode='EDIT')
                newbone = ob_new.data.edit_bones.new(bone.name)
                #parent the bone
John Phan's avatar
John Phan committed
                print("DRI:",dir(newbone))
                parentbone = None
                print("bone name:",bone.name)
                #note bone location is set in the real space or global not local
John Phan's avatar
John Phan committed
                bonesize = bpy.types.Scene.unrealbonesize
                if bone.name != bone.parent:
                    pos_x = bone.bindpos[0]
                    pos_y = bone.bindpos[1]
                    pos_z = bone.bindpos[2]
John Phan's avatar
John Phan committed
                    
                    #print( "LINKING:" , bone.parent ,"j")
                    parentbone = ob_new.data.edit_bones[bone.parent]
                    newbone.parent = parentbone
John Phan's avatar
John Phan committed
                    
                    rotmatrix = bone.bindmat.to_matrix().to_4x4().to_3x3()  # XXX, redundant matrix conversion?
John Phan's avatar
John Phan committed
                    newbone.transform(bone.bindmat.to_matrix().to_4x4(),True,True)
                    #parent_head = parentbone.matrix.to_quaternion().inverse() * parentbone.head
                    #parent_tail = parentbone.matrix.to_quaternion().inverse() * parentbone.tail
                    #location=Vector(pos_x,pos_y,pos_z)
                    #set_position = (parent_tail - parent_head) + location
                    #print("tmp head:",set_position)
                    #pos_x = set_position.x
                    #pos_y = set_position.y
                    #pos_z = set_position.z
                    newbone.head.x = parentbone.head.x + pos_x
                    newbone.head.y = parentbone.head.y + pos_y
                    newbone.head.z = parentbone.head.z + pos_z
                    #print("head:",newbone.head)
                    newbone.tail.x = parentbone.head.x + (pos_x + bonesize * rotmatrix[0][1])
                    newbone.tail.y = parentbone.head.y + (pos_y + bonesize * rotmatrix[1][1])
                    newbone.tail.z = parentbone.head.z + (pos_z + bonesize * rotmatrix[2][1])
John Phan's avatar
John Phan committed
                    #newbone.roll = fixRoll(newbone)
                else:
John Phan's avatar
John Phan committed
                    #print("rotmatrix:",dir(bone.bindmat.to_matrix().resize_4x4()))
                    #rotmatrix = bone.bindmat.to_matrix().resize_4x4().to_3x3()  # XXX, redundant matrix conversion?
John Phan's avatar
John Phan committed
                    rotmatrix = bone.bindmat.to_matrix().to_3x3()  # XXX, redundant matrix conversion?
John Phan's avatar
John Phan committed
                    #newbone.transform(bone.bindmat.to_matrix(),True,True)
                    newbone.head.x = bone.bindpos[0]
                    newbone.head.y = bone.bindpos[1]
                    newbone.head.z = bone.bindpos[2]
                    newbone.tail.x = bone.bindpos[0] + bonesize * rotmatrix[0][1]
                    newbone.tail.y = bone.bindpos[1] + bonesize * rotmatrix[1][1]
                    newbone.tail.z = bone.bindpos[2] + bonesize * rotmatrix[2][1]
John Phan's avatar
John Phan committed
                    #newbone.roll = fixRoll(newbone)
John Phan's avatar
John Phan committed
                    #print("no parent")    
""" 
    

#import psk file
def pskimport(filename,importmesh,importbone,bDebugLogPSK,importmultiuvtextures):
    global DEBUGLOG, plik,vertexes,uvcoord,faceslist,num_faces,facemat,facesmooth,m
    global vertexes_ids,bonesdata,meshesdata,groups,num_materials,skala,flipyz,flipuv,amt,vertices,faces
    points = []
    vertexes = []
    vertices = []
    uvcoord = []
    faceslist = []
    datafaces = []
    faces = []
    facemat = []
    facesmooth = []
    groups = []
    vertexes_ids = []
    bonesdata = {}
    meshesdata ={}
	
    DEBUGLOG = bDebugLogPSK
    print ("--------------------------------------------------")
    print ("---------SCRIPT EXECUTING PYTHON IMPORTER---------")
    print ("--------------------------------------------------")
    print (" DEBUG Log:",bDebugLogPSK)
    print ("Importing file: ", filename)
Luca Bonavita's avatar
Luca Bonavita committed
    
John Phan's avatar
John Phan committed
    plik = open(filename,'rb')
    word(20),i(3)
Luca Bonavita's avatar
Luca Bonavita committed
    
John Phan's avatar
John Phan committed
    #------POINTS------
    print ('reading points')
    word(20)
    data = i(3)
    num_points = data[2]    
    for m in range(num_points):
        v=f(3)
        v1 =v[0]*skala
        v2 =v[1]*skala
        v3 =v[2]*skala
        if flipyz == False:
            points.append([v1,v2,v3])
        if flipyz == True:
            points.append([v1,-v3,v2])
        vertexes_ids.append([])
Luca Bonavita's avatar
Luca Bonavita committed
    
John Phan's avatar
John Phan committed
    #------VERTEXES----
    print ('reading vertexes')
    word(20)
    data = i(3)
    num_vertexes = data[2]
    for m in range(num_vertexes):
        data1 = H(2)
        vertexes.append(points[data1[0]])
        vertices.append(points[data1[0]])
        #vertices.extend(points[data1[0]])
        #vertices.extend([(points[data1[0]][0],points[data1[0]][1],points[data1[0]][2] )])
        #vertices.extend([(points[data1[0]][0],points[data1[0]][1],points[data1[0]][2] )])
        #print(points[data1[0]])
        if flipuv == False:
            uvcoord.append([f(1)[0],1-f(1)[0]])
        if flipuv == True:
            uvcoord.append([f(1)[0],f(1)[0]])
        vertexes_ids[data1[0]].append(m)
        b(2),h(1)
John Phan's avatar
John Phan committed
    #------FACES-------
    print ('reading faces')
    word(20)
    data = i(3)
    num_faces = data[2]
    for m in range(num_faces):
        v0=H(1)[0]
        v1=H(1)[0]
        v2=H(1)[0]
        faceslist.append([v1,v0,v2])
        faces.extend([(v1,v0,v2,0)])
        #faces.append([v1,v0,v2])
        #print((v1,v0,v2,0))
        mat_ids = B(2) 
        facemat.append(mat_ids)
        if str(mat_ids[0]) not in meshesdata:
            meshesdata[str(mat_ids[0])] = []          
        meshesdata[str(mat_ids[0])].append(m)
        facesmooth.append(i(1)[0])
        #datafaces.append([v1,v0,v2],mat_ids
John Phan's avatar
John Phan committed
    #------MATERIALS---
    print ('making materials')
    word(20)
    data = i(3)
    num_materials = data[2]
    for m in range(num_materials):
        name = word(64)
        print ('read materials from',name)
        matdata = bpy.data.materials.new(name)
        #try:
            #mat = Material.Get(namemodel+'-'+str(m))
            #mat = Material.Get(name)
        #except:
            #mat = Material.New(namemodel+'-'+str(m))
            #mat = Material.New(name)
        i(6)
        #make_materials(name,mat)
Luca Bonavita's avatar
Luca Bonavita committed
    
John Phan's avatar
John Phan committed
    #-------BONES------
    print ('reading bones')
    #check_armature()
    check_armature()
    word(20)
    data = i(3)
    num_bones = data[2]
    for m in range(num_bones):
        #print(str(m)) #index
        bonesdata[str(m)] = []
        bonename = word(64)
        bonename = bonename#.strip() 
        bonename = bonename.strip() 
        #print(bonename)#bone name
        bonesdata[str(m)].append(bonename)
        bonesdata[str(m)].append(i(3))
        bonesdata[str(m)].append(f(11))
    make_bone()
    make_bone_parent()
    bones_matrix()
    make_bone_position1()

    
     #-------SKINNING---
    print ('making skinning')
    word(20)
    data = i(3)
    num_groups = data[2]
Luca Bonavita's avatar
Luca Bonavita committed
    
John Phan's avatar
John Phan committed
    for m in range(num_groups):
        w = f(1)[0]
        v_id  = i(1)[0]         
        gr = i(1)[0]
        groups.append([w,v_id,gr]) 
    #create Mesh
    drawmesh()

    print ("IMPORTER PSK Blender 2.6 completed")
def getInputFilename(self,filename,importmesh,importbone,bDebugLogPSK,importmultiuvtextures):
Luca Bonavita's avatar
Luca Bonavita committed
    checktype = filename.split('\\')[-1].split('.')[1]
    print ("------------",filename)
    if checktype.lower() != 'psk':
Luca Bonavita's avatar
Luca Bonavita committed
        print ("  Selected file = ",filename)
        raise (IOError, "The selected input file is not a *.psk file")
        #self.report({'INFO'}, ("Selected file:"+ filename))
    else:
        pskimport(filename,importmesh,importbone,bDebugLogPSK,importmultiuvtextures)
John Phan's avatar
John Phan committed
#import panel
Luca Bonavita's avatar
Luca Bonavita committed
    '''Load a skeleton mesh psk File'''
    bl_idname = "import_scene.psk"
    bl_label = "Import PSK"
John Phan's avatar
John Phan committed
    bl_space_type = "PROPERTIES"
    bl_region_type = "WINDOW"
Luca Bonavita's avatar
Luca Bonavita committed
    # List of operator properties, the attributes will be assigned
    # to the class instance from the operator settings before calling.
    filepath = StringProperty(
            subtype='FILE_PATH',
            )
    filter_glob = StringProperty(
            default="*.psk",
            options={'HIDDEN'},
            )
    importmesh = BoolProperty(
            name="Mesh",
            description="Import mesh only. (not yet build.)",
            default=True,
            )
    importbone = BoolProperty(
            name="Bones",
            description="Import bones only. Current not working yet",
            default=True,
            )
    importmultiuvtextures = BoolProperty(
            name="Single UV Texture(s)",
            description="Single or Multi uv textures",
            default=True,
            )
    bDebugLogPSK = BoolProperty(
            name="Debug Log.txt",
            description="Log the output of raw format. It will save in " \
                        "current file dir. Note this just for testing",
            default=False,
            )
    unrealbonesize = FloatProperty(
            name="Bone Length",
            description="Bone Length from head to tail distance",
Luca Bonavita's avatar
Luca Bonavita committed
    def execute(self, context):
John Phan's avatar
John Phan committed
        bpy.types.Scene.unrealbonesize = self.unrealbonesize
        getInputFilename(self,self.filepath,self.importmesh,self.importbone,self.bDebugLogPSK,self.importmultiuvtextures)
Luca Bonavita's avatar
Luca Bonavita committed
        return {'FINISHED'}
Luca Bonavita's avatar
Luca Bonavita committed
    def invoke(self, context, event):
Campbell Barton's avatar
Campbell Barton committed
        wm = context.window_manager
        wm.fileselect_add(self)
Luca Bonavita's avatar
Luca Bonavita committed
        return {'RUNNING_MODAL'}  
John Phan's avatar
John Phan committed
#import panel psk	
class OBJECT_OT_PSKPath(bpy.types.Operator):
    bl_idname = "object.pskpath"
    bl_label = "PSK Path"
    __doc__ = ""
John Phan's avatar
John Phan committed
    filepath = StringProperty(
            subtype='FILE_PATH',
            )
    filter_glob = StringProperty(
            default="*.psk",
            options={'HIDDEN'},
            )
    importmesh = BoolProperty(
            name="Mesh",
            description="Import mesh only. (not yet build.)",
            default=True,
            )
    importbone = BoolProperty(
            name="Bones",
            description="Import bones only. Current not working yet",
            default=True,
            )
    importmultiuvtextures = BoolProperty(
            name="Single UV Texture(s)",
            description="Single or Multi uv textures",
            default=True,
            )
    bDebugLogPSK = BoolProperty(
            name="Debug Log.txt",
            description="Log the output of raw format. It will save in " \
                        "current file dir. Note this just for testing",
            default=False,
            )
    unrealbonesize = FloatProperty(
            name="Bone Length",
            description="Bone Length from head to tail distance",
            default=1,
            min=0.001,
            max=1000,
            )
    
    def execute(self, context):
        #context.scene.importpskpath = self.properties.filepath
        bpy.types.Scene.unrealbonesize = self.unrealbonesize
        getInputFilename(self,self.filepath,self.importmesh,self.importbone,self.bDebugLogPSK,self.importmultiuvtextures)
        return {'FINISHED'}
        
    def invoke(self, context, event):
        #bpy.context.window_manager.fileselect_add(self)
        wm = context.window_manager
        wm.fileselect_add(self)
        return {'RUNNING_MODAL'}
#import panel psa		
class OBJECT_OT_PSAPath(bpy.types.Operator):
    bl_idname = "object.psapath"
    bl_label = "PSA Path"
    __doc__ = ""

    filepath = StringProperty(name="PSA File Path", description="Filepath used for importing the PSA file", maxlen= 1024, default= "")
    filter_glob = StringProperty(
            default="*.psa",
            options={'HIDDEN'},
            )
    def execute(self, context):
        context.scene.importpsapath = self.properties.filepath
        return {'FINISHED'}
        
    def invoke(self, context, event):
        bpy.context.window_manager.fileselect_add(self)
        return {'RUNNING_MODAL'}
		
class OBJECT_OT_Path(bpy.types.Operator):
    bl_idname = "object.path"
John Phan's avatar
John Phan committed
    __doc__ = ""
    # generic transform props
    view_align = BoolProperty(
            name="Align to View",
            default=False,
            )
    location = FloatVectorProperty(
            name="Location",
            subtype='TRANSLATION',
            )
    rotation = FloatVectorProperty(
            name="Rotation",
            subtype='EULER',
            )
    def execute(self, context):
        return {'FINISHED'}
        
    def invoke(self, context, event):
        me = bpy.data.meshes.new("test")
        obmade = bpy.data.objects.new("TestObject",me)
        print("Create Simple Mesh")
        bpy.data.scenes[0].objects.link(obmade)
        for i in bpy.context.scene.objects: i.select = False #deselect all objects
        obmade.select = True
        bpy.context.scene.objects.active = obmade
        
        verts = [(0,0,0),(2,0,0),(2,0,2)]
        edges = [(0,1),(1,2),(2,0)]
        faces = []
        faces.extend([(0,1,2,0)])
        #me.vertices.add(len(verts))
        #print(dir(me))
        me.vertices.add(len(verts))
        me.tessfaces.add(len(faces))
        for face in me.tessfaces:
            print(dir(face))
        
        me.vertices.foreach_set("co", unpack_list(verts))
        me.tessfaces.foreach_set("vertices_raw", unpack_list(faces))
        me.edges.add(len(edges))
        me.edges.foreach_set("vertices", unpack_list(edges))
        
        #print(len(me.tessfaces))
        me.tessface_uv_textures.new("uvtexture")
        #for uv in me.tessface_uv_textures:
            #print(len(uv.data))
            #print(dir(uv.data[0]))
            #print(dir(uv.data[0].uv1))
        return {'RUNNING_MODAL'}
"""
class OBJECT_OT_Path(bpy.types.Operator):
    bl_idname = "object.path"
    bl_label = "MESH BUILD"
    __doc__ = ""
    # generic transform props
    view_align = BoolProperty(
            name="Align to View",
            default=False,
            )
    location = FloatVectorProperty(
            name="Location",
            subtype='TRANSLATION',
            )
    rotation = FloatVectorProperty(
            name="Rotation",
            subtype='EULER',
            )
    def execute(self, context):
        return {'FINISHED'}
        
    def invoke(self, context, event):
        me = bpy.data.meshes.new("test")
        obmade = bpy.data.objects.new("TestObject",me)
        print("Create Simple Mesh")
        bpy.data.scenes[0].objects.link(obmade)
        for i in bpy.context.scene.objects: i.select = False #deselect all objects
        obmade.select = True
        bpy.context.scene.objects.active = obmade
        
        #bpy.ops.object.mode_set(mode='EDIT')
        #me.from_pydata([(0,0,0),(2,0,0),(2,0,2)],[(1,2),(2,3),(3,1)],[(1,2,3)])
        #me.from_pydata([(0,0,0),(2,0,0),(2,0,2)],[(1,2),(2,3),(3,1)],[(1,2,3)])
        verts = [(0,0,0),(2,0,0),(2,0,2)]
        #faces = [([0, 1, 2])]
        
        faces = []
        #faces.extend([(1,2,3,0)])
        faces.extend([(0,1,2,0)])
        #print(faces[0][0])
        #print(dir(me.tessfaces))
        me.vertices.add(len(verts))
        me.vertices.foreach_set("co", unpack_list(verts))
        
        me.tessfaces.add(len(faces))
        #me.tessfaces.foreach_set("vertices_raw", unpack_list(faces))
        me.tessfaces.foreach_set("vertices", unpack_list(faces))
        #me.tessfaces.foreach_set("vertices_raw", (faces))
        print(len(me.tessfaces))
        me.tessface_uv_textures.new("uvtexture")
        for uv in me.tessface_uv_textures:
            print(len(uv.data))
            print(dir(uv.data[0]))
        bm = bmesh.new()
        bm.to_mesh(me)
        #for v_co in verts:
            #bm.verts.new(v_co)
        for f_idx in faces:
            bm.faces.new([bm.verts[i] for i in f_idx])
        #bm.to_mesh(me)
        #ob = bpy.data.objects.new("TestObject",me)
        #me.update()
        
        #print(dir(me))
        #me.uv_textures.new("uvtexture")
        #for uv in me.uv_textures:
            #print(len(uv.data))
        #from bpy_extras import object_utils
        #object_utils.object_data_add(context, me, operator=self)
        #ob = bpy.data.objects.new("TestObject",me)
        #bpy.context.scene.objects.link(ob) 

        return {'RUNNING_MODAL'}		
"""
"""
class OBJECT_OT_Path(bpy.types.Operator):
    bl_idname = "object.path"
    bl_label = "PSA Path"
    __doc__ = ""
    # generic transform props
    view_align = BoolProperty(
            name="Align to View",
            default=False,
            )
    location = FloatVectorProperty(
            name="Location",
            subtype='TRANSLATION',
            )
    rotation = FloatVectorProperty(
            name="Rotation",
            subtype='EULER',
            )
    def execute(self, context):
        return {'FINISHED'}
        
    def invoke(self, context, event):
        me = bpy.data.meshes.new("test")
        #ob = bpy.data.objects.new("TestObject",me)
        print("Create Simple Mesh")
        #bpy.data.scenes[0].objects.link(ob)
        
        #me.from_pydata([(0,0,0),(2,0,0),(2,0,2)],[(1,2),(2,3),(3,1)],[(1,2,3)])
        #me.from_pydata([(0,0,0),(2,0,0),(2,0,2)],[(1,2),(2,3),(3,1)],[(1,2,3)])
        verts = [(0,0,0),(2,0,0),(2,0,2)]
        faces = [(0, 1, 2)]
        #faces = [([1,2,3])]
        
        
        bm = bmesh.new()
 
        for v_co in verts:
            bm.verts.new(v_co)

        for f_idx in faces:
            bm.faces.new([bm.verts[i] for i in f_idx])

        bm.to_mesh(me)
        ob = bpy.data.objects.new("TestObject",me)
        me.update()
        
        print(dir(me))
        me.uv_textures.new("uvtexture")
        for uv in me.uv_textures:
            print(len(uv.data))
        
        
        
        
        #from bpy_extras import object_utils
        #object_utils.object_data_add(context, me, operator=self)
        bpy.context.scene.objects.link(ob) 

        return {'RUNNING_MODAL'}
"""
"""		
class OBJECT_OT_Path(bpy.types.Operator):
    bl_idname = "object.path"
    bl_label = "PSA Path"
    __doc__ = ""
    # generic transform props
    view_align = BoolProperty(
            name="Align to View",
            default=False,
            )
    location = FloatVectorProperty(
            name="Location",
            subtype='TRANSLATION',
            )
    rotation = FloatVectorProperty(
            name="Rotation",
            subtype='EULER',
            )
    #filepath = StringProperty(name="PSA File Path", description="Filepath used for importing the PSA file", maxlen= 1024, default= "")
    #filter_glob = StringProperty(
            #default="*.psa",
            #options={'HIDDEN'},
            #)
    def execute(self, context):
        #context.scene.importpsapath = self.properties.filepath
        return {'FINISHED'}
        
    def invoke(self, context, event):
        me = bpy.data.meshes.new("test")
        #ob = bpy.data.objects.new("TestObject",me)
        print("Create Simple Mesh")
        #bpy.data.scenes[0].objects.link(ob)
        
        #me.from_pydata([(0,0,0),(2,0,0),(2,0,2)],[(1,2),(2,3),(3,1)],[(1,2,3)])
        #me.from_pydata([(0,0,0),(2,0,0),(2,0,2)],[(1,2),(2,3),(3,1)],[(1,2,3)])
        verts = [(0,0,0),(2,0,0),(2,0,2)]
        faces = [(0, 1, 2, 3)]
        #faces = [([1,2,3])]
        
        
        bm = bmesh.new()
 
        for v_co in verts:
            bm.verts.new(v_co)
John Phan's avatar
John Phan committed

        #for f_idx in faces:
            #bm.faces.new([bm.verts[i] for i in f_idx])
        bm.to_mesh(me)
        me.update()
        from bpy_extras import object_utils
        object_utils.object_data_add(context, me, operator=self)
        
        #bpy.context.scene.objects.link(me) 
      
        #me.from_pydata(verts,[],faces)
        me.vertices.add(len(verts))
        me.tessfaces.add(len(faces))
        
        me.vertices.foreach_set("co", unpack_list(verts))
        me.tessfaces.foreach_set("vertices_raw", (faces))#not working
        
        me.update()
       
        #bpy.context.window_manager.fileselect_add(self)
        return {'RUNNING_MODAL'}		
"""
John Phan's avatar
John Phan committed
#import menu panel tool bar
class VIEW3D_PT_unrealimport_objectmode(bpy.types.Panel):
    bl_space_type = "VIEW_3D"
    bl_region_type = "TOOLS"
    bl_label = "Import PSK/PSA"
    
    @classmethod
    def poll(cls, context):
        return context.active_object

    def draw(self, context):
        layout = self.layout
        rd = context.scene

        row2 = layout.row(align=True)
        row2.operator(OBJECT_OT_PSKPath.bl_idname)                
        row2.operator(OBJECT_OT_PSAPath.bl_idname)        
        row2.operator(OBJECT_OT_Path.bl_idname)        
#import panel
def menu_func(self, context):
    self.layout.operator(IMPORT_OT_psk.bl_idname, text="Skeleton Mesh (.psk)")

John Phan's avatar
John Phan committed
    bpy.utils.register_module(__name__)
    bpy.types.INFO_MT_file_import.append(menu_func)
    
def unregister():
John Phan's avatar
John Phan committed
    bpy.utils.unregister_module(__name__)
    bpy.types.INFO_MT_file_import.remove(menu_func)

if __name__ == "__main__":
Luca Bonavita's avatar
Luca Bonavita committed
    register()
Luca Bonavita's avatar
Luca Bonavita committed
#note this only read the data and will not be place in the scene    
#getInputFilename('C:\\blenderfiles\\BotA.psk') 
#getInputFilename('C:\\blenderfiles\\AA.PSK')
John Phan's avatar
John Phan committed
#getInputFilename('C:\\blender26x\\blender-2.psk')