Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuca Bonavita <mindrones@gmail.com>2010-08-31 06:43:31 +0400
committerLuca Bonavita <mindrones@gmail.com>2010-08-31 06:43:31 +0400
commit01564c0f25797dd213157388291331b66034488e (patch)
tree77cb5ef7d20c7f34db6d1bf10f60236277cddb63 /io_import_scene_unreal_psk.py
parent6cc0943c59112e4679dd2e01a8ee75669a05385e (diff)
== trunk addons ==
- comforming after my commit in bf-blender: - removed the categories from addons names - made 'version' a tuple of integers - added 'api' field - formatted wiki and trackers pages and added where needed (empty pages are yet to be written by the authors though) - more conforming: - 1 tab = 4 spaces - please check everything is fine in case I made some gross mistake
Diffstat (limited to 'io_import_scene_unreal_psk.py')
-rw-r--r--io_import_scene_unreal_psk.py993
1 files changed, 498 insertions, 495 deletions
diff --git a/io_import_scene_unreal_psk.py b/io_import_scene_unreal_psk.py
index 6a04955a..f2844f2c 100644
--- a/io_import_scene_unreal_psk.py
+++ b/io_import_scene_unreal_psk.py
@@ -17,15 +17,18 @@
# ##### END GPL LICENSE BLOCK #####
bl_addon_info = {
- "name": "Import: Unreal Skeleton Mesh(.psk)",
+ "name": "Import Unreal Skeleton Mesh(.psk)",
"author": "Darknet",
- "version": "2.0",
+ "version": (2,0),
"blender": (2, 5, 3),
+ "api": 31667,
"location": "File > Import ",
"description": "Import Unreal Engine (.psk)",
"warning": "",
- "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/File_I-O/Unreal_psk_psa",
- "tracker_url": "https://projects.blender.org/tracker/index.php?func=detail&aid=21366&group_id=153&atid=469",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"
+ "Scripts/File_I-O/Unreal_psk_psa",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=21366&group_id=153&atid=469",
"category": "Import/Export"}
"""
@@ -71,515 +74,515 @@ def unpack_list(list_of_tuples):
return l
"""
class md5_bone:
- bone_index=0
- name=""
- bindpos=[]
- bindmat = mathutils.Quaternion()
- parent=""
- parent_index=0
- blenderbone=None
- roll=0
+ bone_index=0
+ name=""
+ bindpos=[]
+ bindmat = mathutils.Quaternion()
+ parent=""
+ parent_index=0
+ blenderbone=None
+ roll=0
- def __init__(self):
- self.bone_index=0
- self.name=""
- self.bindpos=[0.0]*3
- self.bindmat=[None]*3 #is this how you initilize a 2d-array
- for i in range(3): self.bindmat[i] = [0.0]*3
- self.parent=""
- self.parent_index=0
- self.blenderbone=None
+ def __init__(self):
+ self.bone_index=0
+ self.name=""
+ self.bindpos=[0.0]*3
+ self.bindmat=[None]*3 #is this how you initilize a 2d-array
+ for i in range(3): self.bindmat[i] = [0.0]*3
+ self.parent=""
+ self.parent_index=0
+ self.blenderbone=None
- def dump(self):
- print ("bone index: ", self.bone_index)
- print ("name: ", self.name)
- print ("bind position: ", self.bindpos)
- print ("bind translation matrix: ", self.bindmat)
- print ("parent: ", self.parent)
- print ("parent index: ", self.parent_index)
- print ("blenderbone: ", self.blenderbone)
+ def dump(self):
+ print ("bone index: ", self.bone_index)
+ print ("name: ", self.name)
+ print ("bind position: ", self.bindpos)
+ print ("bind translation matrix: ", self.bindmat)
+ print ("parent: ", self.parent)
+ print ("parent index: ", self.parent_index)
+ print ("blenderbone: ", self.blenderbone)
"""
class md5_bone:
- bone_index=0
- name=""
- bindpos=[]
- bindmat=[]
- scale = []
- parent=""
- parent_index=0
- blenderbone=None
- roll=0
+ bone_index=0
+ name=""
+ bindpos=[]
+ bindmat=[]
+ scale = []
+ parent=""
+ parent_index=0
+ blenderbone=None
+ roll=0
- def __init__(self):
- self.bone_index=0
- self.name=""
- self.bindpos=[0.0]*3
- self.scale=[0.0]*3
- self.bindmat=[None]*3 #is this how you initilize a 2d-array
- for i in range(3): self.bindmat[i] = [0.0]*3
- self.parent=""
- self.parent_index=0
- self.blenderbone=None
+ def __init__(self):
+ self.bone_index=0
+ self.name=""
+ self.bindpos=[0.0]*3
+ self.scale=[0.0]*3
+ self.bindmat=[None]*3 #is this how you initilize a 2d-array
+ for i in range(3): self.bindmat[i] = [0.0]*3
+ self.parent=""
+ self.parent_index=0
+ self.blenderbone=None
- def dump(self):
- print ("bone index: ", self.bone_index)
- print ("name: ", self.name)
- print ("bind position: ", self.bindpos)
- print ("bind translation matrix: ", self.bindmat)
- print ("parent: ", self.parent)
- print ("parent index: ", self.parent_index)
- print ("blenderbone: ", self.blenderbone)
-
-#http://www.blender.org/forum/viewtopic.php?t=13340&sid=8b17d5de07b17960021bbd72cac0495f
+ def dump(self):
+ print ("bone index: ", self.bone_index)
+ print ("name: ", self.name)
+ print ("bind position: ", self.bindpos)
+ print ("bind translation matrix: ", self.bindmat)
+ print ("parent: ", self.parent)
+ print ("parent index: ", self.parent_index)
+ print ("blenderbone: ", self.blenderbone)
+
+#http://www.blender.org/forum/viewtopic.php?t=13340&sid=8b17d5de07b17960021bbd72cac0495f
def fixRollZ(b):
- 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]))
+ 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]))
def fixRoll(b):
- 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]))
-
+ 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]))
+
def pskimport(infile):
- global DEBUGLOG
- print ("--------------------------------------------------")
- print ("---------SCRIPT EXECUTING PYTHON IMPORTER---------")
- print ("--------------------------------------------------")
- print ("Importing file: ", infile)
-
- md5_bones=[]
- pskfile = open(infile,'rb')
- if (DEBUGLOG):
- logpath = infile.replace(".psk", ".txt")
- print("logpath:",logpath)
- logf = open(logpath,'w')
-
- def printlog(strdata):
- if (DEBUGLOG):
- logf.write(strdata)
-
- objName = infile.split('\\')[-1].split('.')[0]
-
- me_ob = bpy.data.meshes.new(objName)
- print("objName:",objName)
- printlog(("New Mesh = " + me_ob.name + "\n"))
- #read general header
- indata = unpack('20s3i',pskfile.read(32))
- #not using the general header at this time
- #==================================================================================================
- # vertex point
- #==================================================================================================
- #read the PNTS0000 header
- indata = unpack('20s3i',pskfile.read(32))
- recCount = indata[3]
- printlog(( "Nbr of PNTS0000 records: " + str(recCount) + "\n"))
- counter = 0
- verts = []
- while counter < recCount:
- counter = counter + 1
- indata = unpack('3f',pskfile.read(12))
- #print(indata[0],indata[1],indata[2])
- verts.extend([(indata[0],indata[1],indata[2])])
- #Tmsh.vertices.append(NMesh.Vert(indata[0],indata[1],indata[2]))
-
- #==================================================================================================
- # UV
- #==================================================================================================
- #read the VTXW0000 header
- indata = unpack('20s3i',pskfile.read(32))
- recCount = indata[3]
- printlog( "Nbr of VTXW0000 records: " + str(recCount)+ "\n")
- counter = 0
- UVCoords = []
- #UVCoords record format = [index to PNTS, U coord, v coord]
- while counter < recCount:
- counter = counter + 1
- indata = unpack('hhffhh',pskfile.read(16))
- UVCoords.append([indata[0],indata[2],indata[3]])
- #print([indata[0],indata[2],indata[3]])
- #print([indata[1],indata[2],indata[3]])
-
- #==================================================================================================
- # Face
- #==================================================================================================
- #read the FACE0000 header
- indata = unpack('20s3i',pskfile.read(32))
- recCount = indata[3]
- printlog( "Nbr of FACE0000 records: "+ str(recCount) + "\n")
- #PSK FACE0000 fields: WdgIdx1|WdgIdx2|WdgIdx3|MatIdx|AuxMatIdx|SmthGrp
- #associate MatIdx to an image, associate SmthGrp to a material
- SGlist = []
- counter = 0
- faces = []
- faceuv = []
- while counter < recCount:
- counter = counter + 1
- indata = unpack('hhhbbi',pskfile.read(12))
- #the psk values are: nWdgIdx1|WdgIdx2|WdgIdx3|MatIdx|AuxMatIdx|SmthGrp
- #indata[0] = index of UVCoords
- #UVCoords[indata[0]]=[index to PNTS, U coord, v coord]
- #UVCoords[indata[0]][0] = index to PNTS
- PNTSA = UVCoords[indata[0]][0]
- PNTSB = UVCoords[indata[1]][0]
- PNTSC = UVCoords[indata[2]][0]
- #print(PNTSA,PNTSB,PNTSC) #face id vertex
- #faces.extend([0,1,2,0])
- faces.extend([PNTSA,PNTSB,PNTSC,0])
- uv = []
- u0 = UVCoords[indata[0]][1]
- v0 = UVCoords[indata[0]][2]
- uv.append([u0,v0])
- u1 = UVCoords[indata[1]][1]
- v1 = UVCoords[indata[1]][2]
- uv.append([u1,v1])
- u2 = UVCoords[indata[2]][1]
- v2 = UVCoords[indata[2]][2]
- uv.append([u2,v2])
- faceuv.append(uv)
- #print("UV: ",u0,v0)
- #update the uv var of the last item in the Tmsh.faces list
- # which is the face just added above
- ##Tmsh.faces[-1].uv = [(u0,v0),(u1,v1),(u2,v2)]
- #print("smooth:",indata[5])
- #collect a list of the smoothing groups
- if SGlist.count(indata[5]) == 0:
- SGlist.append(indata[5])
- print("smooth:",indata[5])
- #assign a material index to the face
- #Tmsh.faces[-1].materialIndex = SGlist.index(indata[5])
- printlog( "Using Materials to represent PSK Smoothing Groups...\n")
- #==========
- # skip something...
- #==========
-
- #==================================================================================================
- # Material
- #==================================================================================================
- ##
- #read the MATT0000 header
- indata = unpack('20s3i',pskfile.read(32))
- recCount = indata[3]
- printlog("Nbr of MATT0000 records: " + str(recCount) + "\n" )
- printlog(" - Not importing any material data now. PSKs are texture wrapped! \n")
- counter = 0
- while counter < recCount:
- counter = counter + 1
- indata = unpack('64s6i',pskfile.read(88))
- ##
-
- #==================================================================================================
- # Bones (Armature)
- #==================================================================================================
- #read the REFSKEL0 header
- indata = unpack('20s3i',pskfile.read(32))
- recCount = indata[3]
- printlog( "Nbr of REFSKEL0 records: " + str(recCount) + "\n")
- Bns = []
- bone = []
- nobone = 0
- #==================================================================================================
- # Bone Data
- #==================================================================================================
- counter = 0
- print ("---PRASE--BONES---")
- while counter < recCount:
- indata = unpack('64s3i11f',pskfile.read(120))
- #print( "DATA",str(indata))
- bone.append(indata)
-
- createbone = md5_bone()
- #temp_name = indata[0][:30]
- temp_name = indata[0]
-
- temp_name = bytes.decode(temp_name)
- temp_name = temp_name.lstrip(" ")
- temp_name = temp_name.rstrip(" ")
- temp_name = temp_name.strip()
- temp_name = temp_name.strip( bytes.decode(b'\x00'))
- print ("temp_name:", temp_name, "||")
- createbone.name = temp_name
- createbone.bone_index = counter
- createbone.parent_index = indata[3]
- createbone.bindpos[0] = indata[8]
- createbone.bindpos[1] = indata[9]
- createbone.bindpos[2] = indata[10]
- createbone.scale[0] = indata[12]
- createbone.scale[1] = indata[13]
- createbone.scale[2] = indata[14]
-
- #w,x,y,z
- if (counter == 0):#main parent
- print("no parent bone")
- createbone.bindmat = mathutils.Quaternion((indata[7],indata[4],indata[5],indata[6]))
- #createbone.bindmat = mathutils.Quaternion((indata[7],-indata[4],-indata[5],-indata[6]))
- else:#parent
- print("parent bone")
- createbone.bindmat = mathutils.Quaternion((indata[7],-indata[4],-indata[5],-indata[6]))
- #createbone.bindmat = mathutils.Quaternion((indata[7],indata[4],indata[5],indata[6]))
-
- md5_bones.append(createbone)
- counter = counter + 1
- bnstr = (str(indata[0]))
- Bns.append(bnstr)
-
- for pbone in md5_bones:
- pbone.parent = md5_bones[pbone.parent_index].name
-
- bonecount = 0
- for armbone in bone:
- temp_name = armbone[0][:30]
- #print ("BONE NAME: ",len(temp_name))
- temp_name=str((temp_name))
- #temp_name = temp_name[1]
- #print ("BONE NAME: ",temp_name)
- bonecount +=1
- print ("-------------------------")
- print ("----Creating--Armature---")
- print ("-------------------------")
-
- #================================================================================================
- #Check armature if exist if so create or update or remove all and addnew bone
- #================================================================================================
- #bpy.ops.object.mode_set(mode='OBJECT')
- meshname ="ArmObject"
- objectname = "armaturedata"
- bfound = False
- arm = None
- for obj in bpy.data.objects:
- if (obj.name == meshname):
- bfound = True
- arm = obj
- break
-
- if bfound == False:
- armdata = bpy.data.armatures.new(objectname)
- ob_new = bpy.data.objects.new(meshname, armdata)
- #ob_new = bpy.data.objects.new(meshname, 'ARMATURE')
- #ob_new.data = armdata
- bpy.context.scene.objects.link(ob_new)
- #bpy.ops.object.mode_set(mode='OBJECT')
- for i in bpy.context.scene.objects: i.select = False #deselect all objects
- ob_new.select = True
- #set current armature to edit the bone
- bpy.context.scene.objects.active = ob_new
- #set mode to able to edit the bone
- bpy.ops.object.mode_set(mode='EDIT')
- #newbone = ob_new.data.edit_bones.new('test')
- #newbone.tail.y = 1
- print("creating bone(s)")
- for bone in md5_bones:
- #print(dir(bone))
- newbone = ob_new.data.edit_bones.new(bone.name)
- #parent the bone
- parentbone = None
- print("bone name:",bone.name)
- #note bone location is set in the real space or global not local
- if bone.name != bone.parent:
-
- pos_x = bone.bindpos[0]
- pos_y = bone.bindpos[1]
- pos_z = bone.bindpos[2]
-
- #print( "LINKING:" , bone.parent ,"j")
- parentbone = ob_new.data.edit_bones[bone.parent]
- newbone.parent = parentbone
- rotmatrix = bone.bindmat.to_matrix().resize4x4().rotation_part()
-
- #parent_head = parentbone.head * parentbone.matrix.to_quat().inverse()
- #parent_tail = parentbone.tail * parentbone.matrix.to_quat().inverse()
- #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[1][0])
- newbone.tail.y = parentbone.head.y + (pos_y + bonesize * rotmatrix[1][1])
- newbone.tail.z = parentbone.head.z + (pos_z + bonesize * rotmatrix[1][2])
- else:
- rotmatrix = bone.bindmat.to_matrix().resize4x4().rotation_part()
- 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[1][0]
- newbone.tail.y = bone.bindpos[1] + bonesize * rotmatrix[1][1]
- newbone.tail.z = bone.bindpos[2] + bonesize * rotmatrix[1][2]
- #print("no parent")
-
- bpy.context.scene.update()
-
- #==================================================================================================
- #END BONE DATA BUILD
- #==================================================================================================
- VtxCol = []
- for x in range(len(Bns)):
- #change the overall darkness of each material in a range between 0.1 and 0.9
- tmpVal = ((float(x)+1.0)/(len(Bns))*0.7)+0.1
- tmpVal = int(tmpVal * 256)
- tmpCol = [tmpVal,tmpVal,tmpVal,0]
- #Change the color of each material slightly
- if x % 3 == 0:
- if tmpCol[0] < 128: tmpCol[0] += 60
- else: tmpCol[0] -= 60
- if x % 3 == 1:
- if tmpCol[1] < 128: tmpCol[1] += 60
- else: tmpCol[1] -= 60
- if x % 3 == 2:
- if tmpCol[2] < 128: tmpCol[2] += 60
- else: tmpCol[2] -= 60
- #Add the material to the mesh
- VtxCol.append(tmpCol)
-
- #==================================================================================================
- # Bone Weight
- #==================================================================================================
- #read the RAWW0000 header
- indata = unpack('20s3i',pskfile.read(32))
- recCount = indata[3]
- printlog( "Nbr of RAWW0000 records: " + str(recCount) +"\n")
- #RAWW0000 fields: Weight|PntIdx|BoneIdx
- RWghts = []
- counter = 0
- while counter < recCount:
- counter = counter + 1
- indata = unpack('fii',pskfile.read(12))
- RWghts.append([indata[1],indata[2],indata[0]])
- #RWghts fields = PntIdx|BoneIdx|Weight
- RWghts.sort()
- printlog( "len(RWghts)=" + str(len(RWghts)) + "\n")
- #Tmsh.update()
-
- #set the Vertex Colors of the faces
- #face.v[n] = RWghts[0]
- #RWghts[1] = index of VtxCol
- """
- for x in range(len(Tmsh.faces)):
- for y in range(len(Tmsh.faces[x].v)):
- #find v in RWghts[n][0]
- findVal = Tmsh.faces[x].v[y].index
- n = 0
- while findVal != RWghts[n][0]:
- n = n + 1
- TmpCol = VtxCol[RWghts[n][1]]
- #check if a vertex has more than one influence
- if n != len(RWghts)-1:
- if RWghts[n][0] == RWghts[n+1][0]:
- #if there is more than one influence, use the one with the greater influence
- #for simplicity only 2 influences are checked, 2nd and 3rd influences are usually very small
- if RWghts[n][2] < RWghts[n+1][2]:
- TmpCol = VtxCol[RWghts[n+1][1]]
- Tmsh.faces[x].col.append(NMesh.Col(TmpCol[0],TmpCol[1],TmpCol[2],0))
- """
- if (DEBUGLOG):
- logf.close()
- #==================================================================================================
- #Building Mesh
- #==================================================================================================
- print("vertex:",len(verts),"faces:",len(faces))
- me_ob.vertices.add(len(verts))
- me_ob.faces.add(len(faces)//4)
+ global DEBUGLOG
+ print ("--------------------------------------------------")
+ print ("---------SCRIPT EXECUTING PYTHON IMPORTER---------")
+ print ("--------------------------------------------------")
+ print ("Importing file: ", infile)
+
+ md5_bones=[]
+ pskfile = open(infile,'rb')
+ if (DEBUGLOG):
+ logpath = infile.replace(".psk", ".txt")
+ print("logpath:",logpath)
+ logf = open(logpath,'w')
+
+ def printlog(strdata):
+ if (DEBUGLOG):
+ logf.write(strdata)
+
+ objName = infile.split('\\')[-1].split('.')[0]
+
+ me_ob = bpy.data.meshes.new(objName)
+ print("objName:",objName)
+ printlog(("New Mesh = " + me_ob.name + "\n"))
+ #read general header
+ indata = unpack('20s3i',pskfile.read(32))
+ #not using the general header at this time
+ #==================================================================================================
+ # vertex point
+ #==================================================================================================
+ #read the PNTS0000 header
+ indata = unpack('20s3i',pskfile.read(32))
+ recCount = indata[3]
+ printlog(( "Nbr of PNTS0000 records: " + str(recCount) + "\n"))
+ counter = 0
+ verts = []
+ while counter < recCount:
+ counter = counter + 1
+ indata = unpack('3f',pskfile.read(12))
+ #print(indata[0],indata[1],indata[2])
+ verts.extend([(indata[0],indata[1],indata[2])])
+ #Tmsh.vertices.append(NMesh.Vert(indata[0],indata[1],indata[2]))
+
+ #==================================================================================================
+ # UV
+ #==================================================================================================
+ #read the VTXW0000 header
+ indata = unpack('20s3i',pskfile.read(32))
+ recCount = indata[3]
+ printlog( "Nbr of VTXW0000 records: " + str(recCount)+ "\n")
+ counter = 0
+ UVCoords = []
+ #UVCoords record format = [index to PNTS, U coord, v coord]
+ while counter < recCount:
+ counter = counter + 1
+ indata = unpack('hhffhh',pskfile.read(16))
+ UVCoords.append([indata[0],indata[2],indata[3]])
+ #print([indata[0],indata[2],indata[3]])
+ #print([indata[1],indata[2],indata[3]])
+
+ #==================================================================================================
+ # Face
+ #==================================================================================================
+ #read the FACE0000 header
+ indata = unpack('20s3i',pskfile.read(32))
+ recCount = indata[3]
+ printlog( "Nbr of FACE0000 records: "+ str(recCount) + "\n")
+ #PSK FACE0000 fields: WdgIdx1|WdgIdx2|WdgIdx3|MatIdx|AuxMatIdx|SmthGrp
+ #associate MatIdx to an image, associate SmthGrp to a material
+ SGlist = []
+ counter = 0
+ faces = []
+ faceuv = []
+ while counter < recCount:
+ counter = counter + 1
+ indata = unpack('hhhbbi',pskfile.read(12))
+ #the psk values are: nWdgIdx1|WdgIdx2|WdgIdx3|MatIdx|AuxMatIdx|SmthGrp
+ #indata[0] = index of UVCoords
+ #UVCoords[indata[0]]=[index to PNTS, U coord, v coord]
+ #UVCoords[indata[0]][0] = index to PNTS
+ PNTSA = UVCoords[indata[0]][0]
+ PNTSB = UVCoords[indata[1]][0]
+ PNTSC = UVCoords[indata[2]][0]
+ #print(PNTSA,PNTSB,PNTSC) #face id vertex
+ #faces.extend([0,1,2,0])
+ faces.extend([PNTSA,PNTSB,PNTSC,0])
+ uv = []
+ u0 = UVCoords[indata[0]][1]
+ v0 = UVCoords[indata[0]][2]
+ uv.append([u0,v0])
+ u1 = UVCoords[indata[1]][1]
+ v1 = UVCoords[indata[1]][2]
+ uv.append([u1,v1])
+ u2 = UVCoords[indata[2]][1]
+ v2 = UVCoords[indata[2]][2]
+ uv.append([u2,v2])
+ faceuv.append(uv)
+ #print("UV: ",u0,v0)
+ #update the uv var of the last item in the Tmsh.faces list
+ # which is the face just added above
+ ##Tmsh.faces[-1].uv = [(u0,v0),(u1,v1),(u2,v2)]
+ #print("smooth:",indata[5])
+ #collect a list of the smoothing groups
+ if SGlist.count(indata[5]) == 0:
+ SGlist.append(indata[5])
+ print("smooth:",indata[5])
+ #assign a material index to the face
+ #Tmsh.faces[-1].materialIndex = SGlist.index(indata[5])
+ printlog( "Using Materials to represent PSK Smoothing Groups...\n")
+ #==========
+ # skip something...
+ #==========
+
+ #==================================================================================================
+ # Material
+ #==================================================================================================
+ ##
+ #read the MATT0000 header
+ indata = unpack('20s3i',pskfile.read(32))
+ recCount = indata[3]
+ printlog("Nbr of MATT0000 records: " + str(recCount) + "\n" )
+ printlog(" - Not importing any material data now. PSKs are texture wrapped! \n")
+ counter = 0
+ while counter < recCount:
+ counter = counter + 1
+ indata = unpack('64s6i',pskfile.read(88))
+ ##
+
+ #==================================================================================================
+ # Bones (Armature)
+ #==================================================================================================
+ #read the REFSKEL0 header
+ indata = unpack('20s3i',pskfile.read(32))
+ recCount = indata[3]
+ printlog( "Nbr of REFSKEL0 records: " + str(recCount) + "\n")
+ Bns = []
+ bone = []
+ nobone = 0
+ #==================================================================================================
+ # Bone Data
+ #==================================================================================================
+ counter = 0
+ print ("---PRASE--BONES---")
+ while counter < recCount:
+ indata = unpack('64s3i11f',pskfile.read(120))
+ #print( "DATA",str(indata))
+ bone.append(indata)
+
+ createbone = md5_bone()
+ #temp_name = indata[0][:30]
+ temp_name = indata[0]
+
+ temp_name = bytes.decode(temp_name)
+ temp_name = temp_name.lstrip(" ")
+ temp_name = temp_name.rstrip(" ")
+ temp_name = temp_name.strip()
+ temp_name = temp_name.strip( bytes.decode(b'\x00'))
+ print ("temp_name:", temp_name, "||")
+ createbone.name = temp_name
+ createbone.bone_index = counter
+ createbone.parent_index = indata[3]
+ createbone.bindpos[0] = indata[8]
+ createbone.bindpos[1] = indata[9]
+ createbone.bindpos[2] = indata[10]
+ createbone.scale[0] = indata[12]
+ createbone.scale[1] = indata[13]
+ createbone.scale[2] = indata[14]
+
+ #w,x,y,z
+ if (counter == 0):#main parent
+ print("no parent bone")
+ createbone.bindmat = mathutils.Quaternion((indata[7],indata[4],indata[5],indata[6]))
+ #createbone.bindmat = mathutils.Quaternion((indata[7],-indata[4],-indata[5],-indata[6]))
+ else:#parent
+ print("parent bone")
+ createbone.bindmat = mathutils.Quaternion((indata[7],-indata[4],-indata[5],-indata[6]))
+ #createbone.bindmat = mathutils.Quaternion((indata[7],indata[4],indata[5],indata[6]))
+
+ md5_bones.append(createbone)
+ counter = counter + 1
+ bnstr = (str(indata[0]))
+ Bns.append(bnstr)
+
+ for pbone in md5_bones:
+ pbone.parent = md5_bones[pbone.parent_index].name
+
+ bonecount = 0
+ for armbone in bone:
+ temp_name = armbone[0][:30]
+ #print ("BONE NAME: ",len(temp_name))
+ temp_name=str((temp_name))
+ #temp_name = temp_name[1]
+ #print ("BONE NAME: ",temp_name)
+ bonecount +=1
+ print ("-------------------------")
+ print ("----Creating--Armature---")
+ print ("-------------------------")
+
+ #================================================================================================
+ #Check armature if exist if so create or update or remove all and addnew bone
+ #================================================================================================
+ #bpy.ops.object.mode_set(mode='OBJECT')
+ meshname ="ArmObject"
+ objectname = "armaturedata"
+ bfound = False
+ arm = None
+ for obj in bpy.data.objects:
+ if (obj.name == meshname):
+ bfound = True
+ arm = obj
+ break
+
+ if bfound == False:
+ armdata = bpy.data.armatures.new(objectname)
+ ob_new = bpy.data.objects.new(meshname, armdata)
+ #ob_new = bpy.data.objects.new(meshname, 'ARMATURE')
+ #ob_new.data = armdata
+ bpy.context.scene.objects.link(ob_new)
+ #bpy.ops.object.mode_set(mode='OBJECT')
+ for i in bpy.context.scene.objects: i.select = False #deselect all objects
+ ob_new.select = True
+ #set current armature to edit the bone
+ bpy.context.scene.objects.active = ob_new
+ #set mode to able to edit the bone
+ bpy.ops.object.mode_set(mode='EDIT')
+ #newbone = ob_new.data.edit_bones.new('test')
+ #newbone.tail.y = 1
+ print("creating bone(s)")
+ for bone in md5_bones:
+ #print(dir(bone))
+ newbone = ob_new.data.edit_bones.new(bone.name)
+ #parent the bone
+ parentbone = None
+ print("bone name:",bone.name)
+ #note bone location is set in the real space or global not local
+ if bone.name != bone.parent:
+
+ pos_x = bone.bindpos[0]
+ pos_y = bone.bindpos[1]
+ pos_z = bone.bindpos[2]
+
+ #print( "LINKING:" , bone.parent ,"j")
+ parentbone = ob_new.data.edit_bones[bone.parent]
+ newbone.parent = parentbone
+ rotmatrix = bone.bindmat.to_matrix().resize4x4().rotation_part()
+
+ #parent_head = parentbone.head * parentbone.matrix.to_quat().inverse()
+ #parent_tail = parentbone.tail * parentbone.matrix.to_quat().inverse()
+ #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[1][0])
+ newbone.tail.y = parentbone.head.y + (pos_y + bonesize * rotmatrix[1][1])
+ newbone.tail.z = parentbone.head.z + (pos_z + bonesize * rotmatrix[1][2])
+ else:
+ rotmatrix = bone.bindmat.to_matrix().resize4x4().rotation_part()
+ 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[1][0]
+ newbone.tail.y = bone.bindpos[1] + bonesize * rotmatrix[1][1]
+ newbone.tail.z = bone.bindpos[2] + bonesize * rotmatrix[1][2]
+ #print("no parent")
+
+ bpy.context.scene.update()
+
+ #==================================================================================================
+ #END BONE DATA BUILD
+ #==================================================================================================
+ VtxCol = []
+ for x in range(len(Bns)):
+ #change the overall darkness of each material in a range between 0.1 and 0.9
+ tmpVal = ((float(x)+1.0)/(len(Bns))*0.7)+0.1
+ tmpVal = int(tmpVal * 256)
+ tmpCol = [tmpVal,tmpVal,tmpVal,0]
+ #Change the color of each material slightly
+ if x % 3 == 0:
+ if tmpCol[0] < 128: tmpCol[0] += 60
+ else: tmpCol[0] -= 60
+ if x % 3 == 1:
+ if tmpCol[1] < 128: tmpCol[1] += 60
+ else: tmpCol[1] -= 60
+ if x % 3 == 2:
+ if tmpCol[2] < 128: tmpCol[2] += 60
+ else: tmpCol[2] -= 60
+ #Add the material to the mesh
+ VtxCol.append(tmpCol)
+
+ #==================================================================================================
+ # Bone Weight
+ #==================================================================================================
+ #read the RAWW0000 header
+ indata = unpack('20s3i',pskfile.read(32))
+ recCount = indata[3]
+ printlog( "Nbr of RAWW0000 records: " + str(recCount) +"\n")
+ #RAWW0000 fields: Weight|PntIdx|BoneIdx
+ RWghts = []
+ counter = 0
+ while counter < recCount:
+ counter = counter + 1
+ indata = unpack('fii',pskfile.read(12))
+ RWghts.append([indata[1],indata[2],indata[0]])
+ #RWghts fields = PntIdx|BoneIdx|Weight
+ RWghts.sort()
+ printlog( "len(RWghts)=" + str(len(RWghts)) + "\n")
+ #Tmsh.update()
+
+ #set the Vertex Colors of the faces
+ #face.v[n] = RWghts[0]
+ #RWghts[1] = index of VtxCol
+ """
+ for x in range(len(Tmsh.faces)):
+ for y in range(len(Tmsh.faces[x].v)):
+ #find v in RWghts[n][0]
+ findVal = Tmsh.faces[x].v[y].index
+ n = 0
+ while findVal != RWghts[n][0]:
+ n = n + 1
+ TmpCol = VtxCol[RWghts[n][1]]
+ #check if a vertex has more than one influence
+ if n != len(RWghts)-1:
+ if RWghts[n][0] == RWghts[n+1][0]:
+ #if there is more than one influence, use the one with the greater influence
+ #for simplicity only 2 influences are checked, 2nd and 3rd influences are usually very small
+ if RWghts[n][2] < RWghts[n+1][2]:
+ TmpCol = VtxCol[RWghts[n+1][1]]
+ Tmsh.faces[x].col.append(NMesh.Col(TmpCol[0],TmpCol[1],TmpCol[2],0))
+ """
+ if (DEBUGLOG):
+ logf.close()
+ #==================================================================================================
+ #Building Mesh
+ #==================================================================================================
+ print("vertex:",len(verts),"faces:",len(faces))
+ me_ob.vertices.add(len(verts))
+ me_ob.faces.add(len(faces)//4)
- me_ob.vertices.foreach_set("co", unpack_list(verts))
-
- me_ob.faces.foreach_set("vertices_raw", faces)
- me_ob.faces.foreach_set("use_smooth", [False] * len(me_ob.faces))
- me_ob.update()
-
- #===================================================================================================
- #UV Setup
- #===================================================================================================
- texture = []
- texturename = "text1"
- #print(dir(bpy.data))
- if (len(faceuv) > 0):
- uvtex = me_ob.uv_textures.new() #add one uv texture
- for i, face in enumerate(me_ob.faces):
- blender_tface= uvtex.data[i] #face
- blender_tface.uv1 = faceuv[i][0] #uv = (0,0)
- blender_tface.uv2 = faceuv[i][1] #uv = (0,0)
- blender_tface.uv3 = faceuv[i][2] #uv = (0,0)
- texture.append(uvtex)
-
- #for tex in me_ob.uv_textures:
- #print("mesh tex:",dir(tex))
- #print((tex.name))
-
- #===================================================================================================
- #Material Setup
- #===================================================================================================
- materialname = "mat"
- materials = []
-
- matdata = bpy.data.materials.new(materialname)
- #color is 0 - 1 not in 0 - 255
- #matdata.mirror_color=(float(0.04),float(0.08),float(0.44))
- matdata.diffuse_color=(float(0.04),float(0.08),float(0.44))#blue color
- #print(dir(me_ob.uv_textures[0].data))
- texdata = None
- texdata = bpy.data.textures[len(bpy.data.textures)-1]
- if (texdata != None):
- #print(texdata.name)
- #print(dir(texdata))
- texdata.name = "texturelist1"
- matdata.active_texture = texdata
- materials.append(matdata)
- #matdata = bpy.data.materials.new(materialname)
- #materials.append(matdata)
- #= make sure the list isnt too big
- for material in materials:
- #add material to the mesh list of materials
- me_ob.materials.link(material)
- #===================================================================================================
- #
- #===================================================================================================
- obmesh = bpy.data.objects.new(objName,me_ob)
- #check if there is a material to set to
- if len(materials) > 0:
- obmesh.active_material = materials[0] #material setup tmp
-
- bpy.context.scene.objects.link(obmesh)
-
- bpy.context.scene.update()
-
- print ("PSK2Blender completed")
+ me_ob.vertices.foreach_set("co", unpack_list(verts))
+
+ me_ob.faces.foreach_set("vertices_raw", faces)
+ me_ob.faces.foreach_set("use_smooth", [False] * len(me_ob.faces))
+ me_ob.update()
+
+ #===================================================================================================
+ #UV Setup
+ #===================================================================================================
+ texture = []
+ texturename = "text1"
+ #print(dir(bpy.data))
+ if (len(faceuv) > 0):
+ uvtex = me_ob.uv_textures.new() #add one uv texture
+ for i, face in enumerate(me_ob.faces):
+ blender_tface= uvtex.data[i] #face
+ blender_tface.uv1 = faceuv[i][0] #uv = (0,0)
+ blender_tface.uv2 = faceuv[i][1] #uv = (0,0)
+ blender_tface.uv3 = faceuv[i][2] #uv = (0,0)
+ texture.append(uvtex)
+
+ #for tex in me_ob.uv_textures:
+ #print("mesh tex:",dir(tex))
+ #print((tex.name))
+
+ #===================================================================================================
+ #Material Setup
+ #===================================================================================================
+ materialname = "mat"
+ materials = []
+
+ matdata = bpy.data.materials.new(materialname)
+ #color is 0 - 1 not in 0 - 255
+ #matdata.mirror_color=(float(0.04),float(0.08),float(0.44))
+ matdata.diffuse_color=(float(0.04),float(0.08),float(0.44))#blue color
+ #print(dir(me_ob.uv_textures[0].data))
+ texdata = None
+ texdata = bpy.data.textures[len(bpy.data.textures)-1]
+ if (texdata != None):
+ #print(texdata.name)
+ #print(dir(texdata))
+ texdata.name = "texturelist1"
+ matdata.active_texture = texdata
+ materials.append(matdata)
+ #matdata = bpy.data.materials.new(materialname)
+ #materials.append(matdata)
+ #= make sure the list isnt too big
+ for material in materials:
+ #add material to the mesh list of materials
+ me_ob.materials.link(material)
+ #===================================================================================================
+ #
+ #===================================================================================================
+ obmesh = bpy.data.objects.new(objName,me_ob)
+ #check if there is a material to set to
+ if len(materials) > 0:
+ obmesh.active_material = materials[0] #material setup tmp
+
+ bpy.context.scene.objects.link(obmesh)
+
+ bpy.context.scene.update()
+
+ print ("PSK2Blender completed")
#End of def pskimport#########################
def getInputFilename(filename):
- checktype = filename.split('\\')[-1].split('.')[1]
- print ("------------",filename)
- if checktype.upper() != 'PSK':
- print (" Selected file = ",filename)
- raise (IOError, "The selected input file is not a *.psk file")
- pskimport(filename)
+ checktype = filename.split('\\')[-1].split('.')[1]
+ print ("------------",filename)
+ if checktype.upper() != 'PSK':
+ print (" Selected file = ",filename)
+ raise (IOError, "The selected input file is not a *.psk file")
+ pskimport(filename)
from bpy.props import *
class IMPORT_OT_psk(bpy.types.Operator):
- '''Load a skeleton mesh psk File'''
- bl_idname = "import_scene.psk"
- bl_label = "Import PSK"
+ '''Load a skeleton mesh psk File'''
+ bl_idname = "import_scene.psk"
+ bl_label = "Import PSK"
- # List of operator properties, the attributes will be assigned
- # to the class instance from the operator settings before calling.
- filepath = StringProperty(name="File Path", description="Filepath used for importing the OBJ file", maxlen= 1024, default= "")
+ # List of operator properties, the attributes will be assigned
+ # to the class instance from the operator settings before calling.
+ filepath = StringProperty(name="File Path", description="Filepath used for importing the OBJ file", maxlen= 1024, default= "")
- def execute(self, context):
- getInputFilename(self.properties.filepath)
- return {'FINISHED'}
+ def execute(self, context):
+ getInputFilename(self.properties.filepath)
+ return {'FINISHED'}
- def invoke(self, context, event):
- wm = context.manager
- wm.add_fileselect(self)
- return {'RUNNING_MODAL'}
+ def invoke(self, context, event):
+ wm = context.manager
+ wm.add_fileselect(self)
+ return {'RUNNING_MODAL'}
def menu_func(self, context):
self.layout.operator(IMPORT_OT_psk.bl_idname, text="Skeleton Mesh (.psk)")
@@ -592,8 +595,8 @@ def unregister():
bpy.types.INFO_MT_file_import.remove(menu_func)
if __name__ == "__main__":
- register()
+ register()
-#note this only read the data and will not be place in the scene
+#note this only read the data and will not be place in the scene
#getInputFilename('C:\\blenderfiles\\BotA.psk')
#getInputFilename('C:\\blenderfiles\\AA.PSK')