17
17
# ##### END GPL LICENSE BLOCK #####
20
"name": "Import Unreal Skeleton Mesh(.psk)",
20
"name": "Import Unreal Skeleton Mesh (.psk)",
21
21
"author": "Darknet",
25
"location": "File > Import ",
26
"description": "Import Unreal Engine (.psk)",
24
"location": "File > Import > Skeleton Mesh (.psk)",
25
"description": "Import Skeleleton Mesh",
28
27
"wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"
29
"Scripts/File_I-O/Unreal_psk_psa",
28
"Scripts/Import-Export/Unreal_psk_psa",
30
29
"tracker_url": "https://projects.blender.org/tracker/index.php?"\
31
"func=detail&aid=21366&group_id=153&atid=469",
32
"category": "Import/Export"}
30
"func=detail&aid=21366",
31
"category": "Import-Export"}
35
34
Version': '2.0' ported by Darknet
37
36
Unreal Tournament PSK file to Blender mesh converter V1.0
38
Author: D.M. Sturgeon (camg188 at the elYsium forum), ported by Darknet
38
-Darknet (Redesign and reworked)
39
-D.M. Sturgeon (camg188 at the elYsium forum)
40
-#2011-01-20 MARIUSZ SZKARADEK GLOGOW POLAND
39
42
Imports a *psk file to a new mesh
45
-Export Text Log From Current Location File (Bool )
55
54
from string import *
56
55
from struct import *
59
#from bpy.props import *
58
from bpy.props import *
59
from bpy_extras.io_utils import unpack_list, unpack_face_list
61
Quaternion = mathutils.Quaternion
63
bpy.types.Scene.unrealbonesize = FloatProperty(
65
description="Bone Length from head to tail distance",
66
default=1,min=0.001,max=1000)
63
68
#output log in to txt file
70
def unpack_list(list_of_tuples):
72
for t in list_of_tuples:
80
bindmat = mathutils.Quaternion()
90
self.bindmat=[None]*3 #is this how you initilize a 2d-array
91
for i in range(3): self.bindmat[i] = [0.0]*3
97
print ("bone index: ", self.bone_index)
98
print ("name: ", self.name)
99
print ("bind position: ", self.bindpos)
100
print ("bind translation matrix: ", self.bindmat)
101
print ("parent: ", self.parent)
102
print ("parent index: ", self.parent_index)
103
print ("blenderbone: ", self.blenderbone)
121
self.bindmat=[None]*3 #is this how you initilize a 2d-array
122
for i in range(3): self.bindmat[i] = [0.0]*3
125
self.blenderbone=None
128
print ("bone index: ", self.bone_index)
129
print ("name: ", self.name)
130
print ("bind position: ", self.bindpos)
131
print ("bind translation matrix: ", self.bindmat)
132
print ("parent: ", self.parent)
133
print ("parent index: ", self.parent_index)
134
print ("blenderbone: ", self.blenderbone)
80
for j in range(0,long):
81
lit = struct.unpack('c',plik.read(1))[0]
83
#print(">",bytes.decode(lit))
92
return struct.unpack(n*'b', plik.read(n))
94
return struct.unpack(n*'B', plik.read(n))
96
return struct.unpack(n*'h', plik.read(n*2))
98
return struct.unpack(n*'H', plik.read(n*2))
100
return struct.unpack(n*'i', plik.read(n*4))
102
return struct.unpack(n*'f', plik.read(n*4))
106
#tess function prefix
108
global DEBUGLOG, plik,vertexes,uvcoord,faceslist,num_faces,facemat,facesmooth,m
109
global vertexes_ids,bonesdata,meshesdata,groups,num_materials,skala,flipyz,flipuv,mat_faceslist
110
global vertices,faces
112
print("[CREATING MESH:]")
113
me_ob = bpy.data.meshes.new('testmesh')
115
print("-Vertices count:",len(vertices))
116
me_ob.vertices.add(len(vertices))
117
print("-Faces count:",len(faces))
118
me_ob.tessfaces.add(len(faces))
119
print("-Creating vertices points...")
120
me_ob.vertices.foreach_set("co", unpack_list(vertices))
121
print("-Creating faces idx...")
122
me_ob.tessfaces.foreach_set("vertices_raw",unpack_list( faces))
123
for face in me_ob.tessfaces:
125
face.use_smooth = facesmooth[face.index]
126
#face.material_index = facemat[face.index]#not yet working
127
print("-Creating UV Texture...")
128
me_ob.tessface_uv_textures.new('uvtexture')
129
#uvtex = me_ob.tessface_uv_textures[0]
130
for uv in me_ob.tessface_uv_textures:
131
for face in me_ob.tessfaces:
132
#uv.data[face.index].uv1.x =
134
#print(uv.data[face.index].uv1)
135
#uv.data[face.index].uv1 = Vector(uvcoord[faces[face.index]][0],uvcoord[face.index][1])
136
print(face.vertices_raw[0],face.vertices_raw[1],face.vertices_raw[2])
137
uv.data[face.index].uv1 = mathutils.Vector((uvcoord[face.vertices_raw[0]][0],uvcoord[face.vertices_raw[0]][1]))
138
uv.data[face.index].uv2 = mathutils.Vector((uvcoord[face.vertices_raw[1]][0],uvcoord[face.vertices_raw[1]][1]))
139
uv.data[face.index].uv3 = mathutils.Vector((uvcoord[face.vertices_raw[2]][0],uvcoord[face.vertices_raw[2]][1]))
141
ob = bpy.data.objects.new("TestObject",me_ob)
143
for bone_id in range(len(bonesdata)):
144
bonedata = bonesdata[str(bone_id)]
145
namebone = bonedata[0]#.strip()[-25:]
146
#print("NAME:",namebone)
147
ob.vertex_groups.new(namebone)
149
bpy.context.scene.objects.link(ob)
152
def check_armature():
153
global DEBUGLOG, plik,vertexes,uvcoord,faceslist,num_faces,facemat,facesmooth,m
154
global vertexes_ids,bonesdata,meshesdata,groups,num_materials,skala,flipyz,flipuv,amt
157
bpy.ops.object.mode_set(mode='OBJECT')
158
for i in bpy.context.scene.objects: i.select = False #deselect all objects
164
ob = bpy.context.object
170
bpy.ops.object.mode_set(mode='EDIT')
171
bpy.context.scene.update()
174
global DEBUGLOG, plik,vertexes,uvcoord,faceslist,num_faces,facemat,facesmooth,m
175
global vertexes_ids,bonesdata,meshesdata,groups,num_materials,skala,flipyz,flipuv,amt
181
for bone_id in range(len(bonesdata)):
182
bonedata = bonesdata[str(bone_id)]
183
namebone = bonedata[0]#.strip()[-25:]
184
newbone = amt.edit_bones.new(namebone)
185
#those are need to show in the scene
186
newbone.head = (0,0,0)
187
newbone.tail = (0,0,1)
188
bonenames.append(namebone)
189
bpy.context.scene.update()
191
def make_bone_parent():
192
global DEBUGLOG, plik,vertexes,uvcoord,faceslist,num_faces,facemat,facesmooth,m
193
global vertexes_ids,bonesdata,meshesdata,groups,num_materials,skala,flipyz,flipuv,amt
197
print ('make bone parent')
198
for bone_id in range(len(bonesdata)):
199
bonedata = bonesdata[str(bone_id)]
200
namebone = bonenames[bone_id]
201
nameparent = bonenames[bonedata[1][2]]
203
if nameparent != None:#make sure it has name
204
parentbone = amt.edit_bones[nameparent]
205
bonecurrnet = amt.edit_bones[namebone]
206
bonecurrnet.parent = parentbone
207
bpy.context.scene.update()
209
#make bone martix set
211
global DEBUGLOG, plik,vertexes,uvcoord,faceslist,num_faces,facemat,facesmooth,m
212
global vertexes_ids,bonesdata,meshesdata,groups,num_materials,skala,flipyz,flipuv,amt
214
for bone_id in range(len(bonesdata)):
215
bonedata = bonesdata[str(bone_id)]
216
namebone = bonedata[0]#.strip()[-25:]
217
nameparent = bonenames[bonedata[1][2]]
218
pos = bonedata[2][4:7]
219
rot = bonedata[2][0:4]
220
qx,qy,qz,qw = rot[0],rot[1],rot[2],rot[3]
221
#print("Quaternion:",qx,qy,qz,qw)
223
rot = mathutils.Quaternion((qw,-qx,-qy,-qz))
225
rot = mathutils.Quaternion((qw,qx,qy,qz))
226
matrix = mathutils.Matrix()
227
rot = rot.to_matrix().inverted()
229
matrix[0][:3] = rot[0]
230
matrix[1][:3] = rot[1]
231
matrix[2][:3] = rot[2]
234
bonedata.append(matrix*bonesdata[str(bonedata[1][2])][3])
236
bonedata.append(matrix)
237
bpy.context.scene.update()
240
def make_bone_position():
241
print ('make bone position')
242
bpy.ops.object.mode_set(mode='EDIT')
243
for bone_id in range(len(bonesdata)):
244
bonedata = bonesdata[str(bone_id)]
245
namebone = bonedata[0]#.strip()[-25:]
246
bone = amt.edit_bones[namebone]
247
bone.transform(bonedata[3], scale=True, roll=True)
248
bvec = bone.tail- bone.head
250
bone.tail = bone.head + 0.1 * bvec
251
#bone.tail = bone.head + 1 * bvec
252
bpy.context.scene.update()
255
def make_bone_position1():
256
print ('make bone position')
257
bpy.ops.object.mode_set(mode='EDIT')
258
for bone_id in range(len(bonesdata)):
259
bonedata = bonesdata[str(bone_id)]
260
namebone = bonedata[0]#.strip()[-25:]
261
pos = bonedata[2][4:7]
266
pos = [pos1,pos2,pos3]
268
pos = [pos1,-pos3,pos2]
269
rot = bonedata[2][0:4]
270
qx,qy,qz,qw = rot[0],rot[1],rot[2],rot[3]
272
rot = mathutils.Quaternion((qw,-qx,-qy,-qz))
274
rot = mathutils.Quaternion((qw,qx,qy,qz))
275
#rot = rot.toMatrix().invert()
276
rot = rot.to_matrix().inverted()
277
bone = amt.edit_bones[namebone]
278
#print("BONES:",amt.bones[0])
281
bone.head = bone.parent.head+mathutils.Vector(pos) * bone.parent.matrix
284
#print("matrix:",bone.parent.matrix)
286
tempM = rot.to_4x4()*bone.parent.matrix
288
bone.transform(tempM, scale=False, roll=True)
289
#bone.matrix_local = tempM
291
bone.head = mathutils.Vector(pos)
293
bone.transform(rot, scale=False, roll=True)
294
#bone.matrix_local = rot
295
bvec = bone.tail- bone.head
297
bone.tail = bone.head + 0.1 * bvec
298
#bone.tail = bone.head + 1 * bvec
136
301
#http://www.blender.org/forum/viewtopic.php?t=13340&sid=8b17d5de07b17960021bbd72cac0495f
138
303
v = (b.tail-b.head)/b.length
147
312
b.roll -= math.degrees(math.atan2(v[0]*v[2]*(1 - v[1]),v[0]*v[0] + v[1]*v[2]*v[2]))
149
def pskimport(infile):
313
""" #did not port this yet unstable but work in some ways
314
def make_bone_position3():
315
for bone in md5_bones:
317
bpy.ops.object.mode_set(mode='EDIT')
318
newbone = ob_new.data.edit_bones.new(bone.name)
320
print("DRI:",dir(newbone))
322
print("bone name:",bone.name)
323
#note bone location is set in the real space or global not local
324
bonesize = bpy.types.Scene.unrealbonesize
325
if bone.name != bone.parent:
327
pos_x = bone.bindpos[0]
328
pos_y = bone.bindpos[1]
329
pos_z = bone.bindpos[2]
331
#print( "LINKING:" , bone.parent ,"j")
332
parentbone = ob_new.data.edit_bones[bone.parent]
333
newbone.parent = parentbone
335
rotmatrix = bone.bindmat.to_matrix().to_4x4().to_3x3() # XXX, redundant matrix conversion?
336
newbone.transform(bone.bindmat.to_matrix().to_4x4(),True,True)
337
#parent_head = parentbone.matrix.to_quaternion().inverse() * parentbone.head
338
#parent_tail = parentbone.matrix.to_quaternion().inverse() * parentbone.tail
339
#location=Vector(pos_x,pos_y,pos_z)
340
#set_position = (parent_tail - parent_head) + location
341
#print("tmp head:",set_position)
343
#pos_x = set_position.x
344
#pos_y = set_position.y
345
#pos_z = set_position.z
348
newbone.head.x = parentbone.head.x + pos_x
349
newbone.head.y = parentbone.head.y + pos_y
350
newbone.head.z = parentbone.head.z + pos_z
351
#print("head:",newbone.head)
352
newbone.tail.x = parentbone.head.x + (pos_x + bonesize * rotmatrix[0][1])
353
newbone.tail.y = parentbone.head.y + (pos_y + bonesize * rotmatrix[1][1])
354
newbone.tail.z = parentbone.head.z + (pos_z + bonesize * rotmatrix[2][1])
355
#newbone.roll = fixRoll(newbone)
357
#print("rotmatrix:",dir(bone.bindmat.to_matrix().resize_4x4()))
358
#rotmatrix = bone.bindmat.to_matrix().resize_4x4().to_3x3() # XXX, redundant matrix conversion?
359
rotmatrix = bone.bindmat.to_matrix().to_3x3() # XXX, redundant matrix conversion?
360
#newbone.transform(bone.bindmat.to_matrix(),True,True)
361
newbone.head.x = bone.bindpos[0]
362
newbone.head.y = bone.bindpos[1]
363
newbone.head.z = bone.bindpos[2]
364
newbone.tail.x = bone.bindpos[0] + bonesize * rotmatrix[0][1]
365
newbone.tail.y = bone.bindpos[1] + bonesize * rotmatrix[1][1]
366
newbone.tail.z = bone.bindpos[2] + bonesize * rotmatrix[2][1]
367
#newbone.roll = fixRoll(newbone)
373
def pskimport(filename,importmesh,importbone,bDebugLogPSK,importmultiuvtextures):
374
global DEBUGLOG, plik,vertexes,uvcoord,faceslist,num_faces,facemat,facesmooth,m
375
global vertexes_ids,bonesdata,meshesdata,groups,num_materials,skala,flipyz,flipuv,amt,vertices,faces
390
DEBUGLOG = bDebugLogPSK
151
391
print ("--------------------------------------------------")
152
392
print ("---------SCRIPT EXECUTING PYTHON IMPORTER---------")
153
393
print ("--------------------------------------------------")
154
print ("Importing file: ", infile)
157
pskfile = open(infile,'rb')
159
logpath = infile.replace(".psk", ".txt")
160
print("logpath:",logpath)
161
logf = open(logpath,'w')
163
def printlog(strdata):
167
objName = infile.split('\\')[-1].split('.')[0]
169
me_ob = bpy.data.meshes.new(objName)
170
print("objName:",objName)
171
printlog(("New Mesh = " + me_ob.name + "\n"))
173
indata = unpack('20s3i',pskfile.read(32))
174
#not using the general header at this time
175
#==================================================================================================
177
#==================================================================================================
178
#read the PNTS0000 header
179
indata = unpack('20s3i',pskfile.read(32))
181
printlog(( "Nbr of PNTS0000 records: " + str(recCount) + "\n"))
184
while counter < recCount:
185
counter = counter + 1
186
indata = unpack('3f',pskfile.read(12))
187
#print(indata[0],indata[1],indata[2])
188
verts.extend([(indata[0],indata[1],indata[2])])
189
#Tmsh.vertices.append(NMesh.Vert(indata[0],indata[1],indata[2]))
191
#==================================================================================================
193
#==================================================================================================
194
#read the VTXW0000 header
195
indata = unpack('20s3i',pskfile.read(32))
197
printlog( "Nbr of VTXW0000 records: " + str(recCount)+ "\n")
200
#UVCoords record format = [index to PNTS, U coord, v coord]
201
while counter < recCount:
202
counter = counter + 1
203
indata = unpack('hhffhh',pskfile.read(16))
204
UVCoords.append([indata[0],indata[2],indata[3]])
205
#print([indata[0],indata[2],indata[3]])
206
#print([indata[1],indata[2],indata[3]])
208
#==================================================================================================
210
#==================================================================================================
211
#read the FACE0000 header
212
indata = unpack('20s3i',pskfile.read(32))
214
printlog( "Nbr of FACE0000 records: "+ str(recCount) + "\n")
215
#PSK FACE0000 fields: WdgIdx1|WdgIdx2|WdgIdx3|MatIdx|AuxMatIdx|SmthGrp
216
#associate MatIdx to an image, associate SmthGrp to a material
221
while counter < recCount:
222
counter = counter + 1
223
indata = unpack('hhhbbi',pskfile.read(12))
224
#the psk values are: nWdgIdx1|WdgIdx2|WdgIdx3|MatIdx|AuxMatIdx|SmthGrp
225
#indata[0] = index of UVCoords
226
#UVCoords[indata[0]]=[index to PNTS, U coord, v coord]
227
#UVCoords[indata[0]][0] = index to PNTS
228
PNTSA = UVCoords[indata[0]][0]
229
PNTSB = UVCoords[indata[1]][0]
230
PNTSC = UVCoords[indata[2]][0]
231
#print(PNTSA,PNTSB,PNTSC) #face id vertex
232
#faces.extend([0,1,2,0])
233
faces.extend([PNTSA,PNTSB,PNTSC,0])
235
u0 = UVCoords[indata[0]][1]
236
v0 = UVCoords[indata[0]][2]
238
u1 = UVCoords[indata[1]][1]
239
v1 = UVCoords[indata[1]][2]
241
u2 = UVCoords[indata[2]][1]
242
v2 = UVCoords[indata[2]][2]
246
#update the uv var of the last item in the Tmsh.faces list
247
# which is the face just added above
248
##Tmsh.faces[-1].uv = [(u0,v0),(u1,v1),(u2,v2)]
249
#print("smooth:",indata[5])
250
#collect a list of the smoothing groups
251
if SGlist.count(indata[5]) == 0:
252
SGlist.append(indata[5])
253
print("smooth:",indata[5])
254
#assign a material index to the face
255
#Tmsh.faces[-1].materialIndex = SGlist.index(indata[5])
256
printlog( "Using Materials to represent PSK Smoothing Groups...\n")
261
#==================================================================================================
263
#==================================================================================================
265
#read the MATT0000 header
266
indata = unpack('20s3i',pskfile.read(32))
268
printlog("Nbr of MATT0000 records: " + str(recCount) + "\n" )
269
printlog(" - Not importing any material data now. PSKs are texture wrapped! \n")
271
while counter < recCount:
272
counter = counter + 1
273
indata = unpack('64s6i',pskfile.read(88))
276
#==================================================================================================
278
#==================================================================================================
279
#read the REFSKEL0 header
280
indata = unpack('20s3i',pskfile.read(32))
282
printlog( "Nbr of REFSKEL0 records: " + str(recCount) + "\n")
286
#==================================================================================================
288
#==================================================================================================
290
print ("---PRASE--BONES---")
291
while counter < recCount:
292
indata = unpack('64s3i11f',pskfile.read(120))
293
#print( "DATA",str(indata))
296
createbone = md5_bone()
297
#temp_name = indata[0][:30]
298
temp_name = indata[0]
300
temp_name = bytes.decode(temp_name)
301
temp_name = temp_name.lstrip(" ")
302
temp_name = temp_name.rstrip(" ")
303
temp_name = temp_name.strip()
304
temp_name = temp_name.strip( bytes.decode(b'\x00'))
305
print ("temp_name:", temp_name, "||")
306
createbone.name = temp_name
307
createbone.bone_index = counter
308
createbone.parent_index = indata[3]
309
createbone.bindpos[0] = indata[8]
310
createbone.bindpos[1] = indata[9]
311
createbone.bindpos[2] = indata[10]
312
createbone.scale[0] = indata[12]
313
createbone.scale[1] = indata[13]
314
createbone.scale[2] = indata[14]
317
if (counter == 0):#main parent
318
print("no parent bone")
319
createbone.bindmat = mathutils.Quaternion((indata[7],indata[4],indata[5],indata[6]))
320
#createbone.bindmat = mathutils.Quaternion((indata[7],-indata[4],-indata[5],-indata[6]))
323
createbone.bindmat = mathutils.Quaternion((indata[7],-indata[4],-indata[5],-indata[6]))
324
#createbone.bindmat = mathutils.Quaternion((indata[7],indata[4],indata[5],indata[6]))
326
md5_bones.append(createbone)
327
counter = counter + 1
328
bnstr = (str(indata[0]))
331
for pbone in md5_bones:
332
pbone.parent = md5_bones[pbone.parent_index].name
336
temp_name = armbone[0][:30]
337
#print ("BONE NAME: ",len(temp_name))
338
temp_name=str((temp_name))
339
#temp_name = temp_name[1]
340
#print ("BONE NAME: ",temp_name)
342
print ("-------------------------")
343
print ("----Creating--Armature---")
344
print ("-------------------------")
346
#================================================================================================
347
#Check armature if exist if so create or update or remove all and addnew bone
348
#================================================================================================
349
#bpy.ops.object.mode_set(mode='OBJECT')
350
meshname ="ArmObject"
351
objectname = "armaturedata"
354
for obj in bpy.data.objects:
355
if (obj.name == meshname):
361
armdata = bpy.data.armatures.new(objectname)
362
ob_new = bpy.data.objects.new(meshname, armdata)
363
#ob_new = bpy.data.objects.new(meshname, 'ARMATURE')
364
#ob_new.data = armdata
365
bpy.context.scene.objects.link(ob_new)
366
#bpy.ops.object.mode_set(mode='OBJECT')
367
for i in bpy.context.scene.objects: i.select = False #deselect all objects
369
#set current armature to edit the bone
370
bpy.context.scene.objects.active = ob_new
371
#set mode to able to edit the bone
372
bpy.ops.object.mode_set(mode='EDIT')
373
#newbone = ob_new.data.edit_bones.new('test')
375
print("creating bone(s)")
376
for bone in md5_bones:
378
newbone = ob_new.data.edit_bones.new(bone.name)
381
print("bone name:",bone.name)
382
#note bone location is set in the real space or global not local
383
if bone.name != bone.parent:
385
pos_x = bone.bindpos[0]
386
pos_y = bone.bindpos[1]
387
pos_z = bone.bindpos[2]
389
#print( "LINKING:" , bone.parent ,"j")
390
parentbone = ob_new.data.edit_bones[bone.parent]
391
newbone.parent = parentbone
392
rotmatrix = bone.bindmat.to_matrix().resize4x4().rotation_part()
394
#parent_head = parentbone.head * parentbone.matrix.to_quat().inverse()
395
#parent_tail = parentbone.tail * parentbone.matrix.to_quat().inverse()
396
#location=Vector(pos_x,pos_y,pos_z)
397
#set_position = (parent_tail - parent_head) + location
398
#print("tmp head:",set_position)
400
#pos_x = set_position.x
401
#pos_y = set_position.y
402
#pos_z = set_position.z
404
newbone.head.x = parentbone.head.x + pos_x
405
newbone.head.y = parentbone.head.y + pos_y
406
newbone.head.z = parentbone.head.z + pos_z
407
print("head:",newbone.head)
408
newbone.tail.x = parentbone.head.x + (pos_x + bonesize * rotmatrix[1][0])
409
newbone.tail.y = parentbone.head.y + (pos_y + bonesize * rotmatrix[1][1])
410
newbone.tail.z = parentbone.head.z + (pos_z + bonesize * rotmatrix[1][2])
412
rotmatrix = bone.bindmat.to_matrix().resize4x4().rotation_part()
413
newbone.head.x = bone.bindpos[0]
414
newbone.head.y = bone.bindpos[1]
415
newbone.head.z = bone.bindpos[2]
416
newbone.tail.x = bone.bindpos[0] + bonesize * rotmatrix[1][0]
417
newbone.tail.y = bone.bindpos[1] + bonesize * rotmatrix[1][1]
418
newbone.tail.z = bone.bindpos[2] + bonesize * rotmatrix[1][2]
421
bpy.context.scene.update()
423
#==================================================================================================
425
#==================================================================================================
427
for x in range(len(Bns)):
428
#change the overall darkness of each material in a range between 0.1 and 0.9
429
tmpVal = ((float(x)+1.0)/(len(Bns))*0.7)+0.1
430
tmpVal = int(tmpVal * 256)
431
tmpCol = [tmpVal,tmpVal,tmpVal,0]
432
#Change the color of each material slightly
434
if tmpCol[0] < 128: tmpCol[0] += 60
435
else: tmpCol[0] -= 60
437
if tmpCol[1] < 128: tmpCol[1] += 60
438
else: tmpCol[1] -= 60
440
if tmpCol[2] < 128: tmpCol[2] += 60
441
else: tmpCol[2] -= 60
442
#Add the material to the mesh
443
VtxCol.append(tmpCol)
445
#==================================================================================================
447
#==================================================================================================
448
#read the RAWW0000 header
449
indata = unpack('20s3i',pskfile.read(32))
451
printlog( "Nbr of RAWW0000 records: " + str(recCount) +"\n")
452
#RAWW0000 fields: Weight|PntIdx|BoneIdx
455
while counter < recCount:
456
counter = counter + 1
457
indata = unpack('fii',pskfile.read(12))
458
RWghts.append([indata[1],indata[2],indata[0]])
459
#RWghts fields = PntIdx|BoneIdx|Weight
461
printlog( "len(RWghts)=" + str(len(RWghts)) + "\n")
464
#set the Vertex Colors of the faces
465
#face.v[n] = RWghts[0]
466
#RWghts[1] = index of VtxCol
468
for x in range(len(Tmsh.faces)):
469
for y in range(len(Tmsh.faces[x].v)):
470
#find v in RWghts[n][0]
471
findVal = Tmsh.faces[x].v[y].index
473
while findVal != RWghts[n][0]:
475
TmpCol = VtxCol[RWghts[n][1]]
476
#check if a vertex has more than one influence
477
if n != len(RWghts)-1:
478
if RWghts[n][0] == RWghts[n+1][0]:
479
#if there is more than one influence, use the one with the greater influence
480
#for simplicity only 2 influences are checked, 2nd and 3rd influences are usually very small
481
if RWghts[n][2] < RWghts[n+1][2]:
482
TmpCol = VtxCol[RWghts[n+1][1]]
483
Tmsh.faces[x].col.append(NMesh.Col(TmpCol[0],TmpCol[1],TmpCol[2],0))
487
#==================================================================================================
489
#==================================================================================================
490
print("vertex:",len(verts),"faces:",len(faces))
491
me_ob.vertices.add(len(verts))
492
me_ob.faces.add(len(faces)//4)
494
me_ob.vertices.foreach_set("co", unpack_list(verts))
496
me_ob.faces.foreach_set("vertices_raw", faces)
497
me_ob.faces.foreach_set("use_smooth", [False] * len(me_ob.faces))
500
#===================================================================================================
502
#===================================================================================================
504
texturename = "text1"
505
#print(dir(bpy.data))
506
if (len(faceuv) > 0):
507
uvtex = me_ob.uv_textures.new() #add one uv texture
508
for i, face in enumerate(me_ob.faces):
509
blender_tface= uvtex.data[i] #face
510
blender_tface.uv1 = faceuv[i][0] #uv = (0,0)
511
blender_tface.uv2 = faceuv[i][1] #uv = (0,0)
512
blender_tface.uv3 = faceuv[i][2] #uv = (0,0)
513
texture.append(uvtex)
515
#for tex in me_ob.uv_textures:
516
#print("mesh tex:",dir(tex))
519
#===================================================================================================
521
#===================================================================================================
525
matdata = bpy.data.materials.new(materialname)
526
#color is 0 - 1 not in 0 - 255
527
#matdata.mirror_color=(float(0.04),float(0.08),float(0.44))
528
matdata.diffuse_color=(float(0.04),float(0.08),float(0.44))#blue color
529
#print(dir(me_ob.uv_textures[0].data))
531
texdata = bpy.data.textures[len(bpy.data.textures)-1]
532
if (texdata != None):
535
texdata.name = "texturelist1"
536
matdata.active_texture = texdata
537
materials.append(matdata)
538
#matdata = bpy.data.materials.new(materialname)
539
#materials.append(matdata)
540
#= make sure the list isnt too big
541
for material in materials:
542
#add material to the mesh list of materials
543
me_ob.materials.append(material)
544
#===================================================================================================
546
#===================================================================================================
547
obmesh = bpy.data.objects.new(objName,me_ob)
548
#check if there is a material to set to
549
if len(materials) > 0:
550
obmesh.active_material = materials[0] #material setup tmp
552
bpy.context.scene.objects.link(obmesh)
554
bpy.context.scene.update()
556
print ("PSK2Blender completed")
394
print (" DEBUG Log:",bDebugLogPSK)
395
print ("Importing file: ", filename)
397
plik = open(filename,'rb')
401
print ('reading points')
405
for m in range(num_points):
411
points.append([v1,v2,v3])
413
points.append([v1,-v3,v2])
414
vertexes_ids.append([])
417
print ('reading vertexes')
420
num_vertexes = data[2]
421
for m in range(num_vertexes):
423
vertexes.append(points[data1[0]])
424
vertices.append(points[data1[0]])
425
#vertices.extend(points[data1[0]])
426
#vertices.extend([(points[data1[0]][0],points[data1[0]][1],points[data1[0]][2] )])
427
#vertices.extend([(points[data1[0]][0],points[data1[0]][1],points[data1[0]][2] )])
428
#print(points[data1[0]])
430
uvcoord.append([f(1)[0],1-f(1)[0]])
432
uvcoord.append([f(1)[0],f(1)[0]])
433
vertexes_ids[data1[0]].append(m)
438
print ('reading faces')
442
for m in range(num_faces):
446
faceslist.append([v1,v0,v2])
447
faces.extend([(v1,v0,v2,0)])
448
#faces.append([v1,v0,v2])
451
facemat.append(mat_ids)
452
if str(mat_ids[0]) not in meshesdata:
453
meshesdata[str(mat_ids[0])] = []
454
meshesdata[str(mat_ids[0])].append(m)
455
facesmooth.append(i(1)[0])
456
#datafaces.append([v1,v0,v2],mat_ids
459
print ('making materials')
462
num_materials = data[2]
463
for m in range(num_materials):
465
print ('read materials from',name)
466
matdata = bpy.data.materials.new(name)
468
#mat = Material.Get(namemodel+'-'+str(m))
469
#mat = Material.Get(name)
471
#mat = Material.New(namemodel+'-'+str(m))
472
#mat = Material.New(name)
474
#make_materials(name,mat)
477
print ('reading bones')
483
for m in range(num_bones):
484
#print(str(m)) #index
485
bonesdata[str(m)] = []
487
bonename = bonename#.strip()
488
bonename = bonename.strip()
489
#print(bonename)#bone name
490
bonesdata[str(m)].append(bonename)
491
bonesdata[str(m)].append(i(3))
492
bonesdata[str(m)].append(f(11))
496
make_bone_position1()
500
print ('making skinning')
505
for m in range(num_groups):
509
groups.append([w,v_id,gr])
513
print ("IMPORTER PSK Blender 2.6 completed")
557
514
#End of def pskimport#########################
559
def getInputFilename(filename):
516
def psaimport(filename):
517
global plik,bonesdata,animdata,anim_offset,animation_names
520
animation_num_bones = []
521
animation_num_keys = []
522
animation_loc_keys = []
523
animation_rot_keys = []
525
plik = open(filename,'rb')
526
print (word(20),i(3))
529
#check_armature_for_psa()
534
for m in range(num_bones):
535
bonesdata[str(m)] = []
537
bonesdata[str(m)].append(name)
538
bonesdata[str(m)].append(i(3))
539
bonesdata[str(m)].append(f(11))
542
#--------ANIMATIONS-INFO
546
for m in range(data[2]):
547
name_animation = word(64)#name animation
548
print("NAME:",name_animation)
549
animation_names.append(name_animation)
550
word(64)#name of owner of animation ?
551
data = i(4)#num bones - 0 - 0 - num keys for all bones for this animation
553
animation_num_bones.append(num_bones)
557
animation_num_keys.append(num_keys)
560
#--------ANIMATIONS-KEYS
566
for m in range(len(animation_names)):
567
anim_name = animation_names[m]
568
anim_bones = animation_num_bones[m]
569
anim_keys = animation_num_keys[m]
570
anim_offset[anim_name] = []
571
anim_offset[anim_name].append(seek)
572
anim_offset[anim_name].append(anim_keys)
573
anim_offset[anim_name].append(anim_bones)
574
seek+=anim_keys*anim_bones*32
577
def getInputFilename(self,filename,importmesh,importbone,bDebugLogPSK,importmultiuvtextures):
560
578
checktype = filename.split('\\')[-1].split('.')[1]
561
579
print ("------------",filename)
562
if checktype.upper() != 'PSK':
580
if checktype.lower() != 'psk':
563
581
print (" Selected file = ",filename)
564
582
raise (IOError, "The selected input file is not a *.psk file")
567
from bpy.props import *
583
#self.report({'INFO'}, ("Selected file:"+ filename))
585
pskimport(filename,importmesh,importbone,bDebugLogPSK,importmultiuvtextures)
569
587
class IMPORT_OT_psk(bpy.types.Operator):
570
588
'''Load a skeleton mesh psk File'''
571
589
bl_idname = "import_scene.psk"
572
590
bl_label = "Import PSK"
591
bl_space_type = "PROPERTIES"
592
bl_region_type = "WINDOW"
593
bl_options = {'UNDO'}
574
595
# List of operator properties, the attributes will be assigned
575
596
# to the class instance from the operator settings before calling.
576
filepath = StringProperty(name="File Path", description="Filepath used for importing the OBJ file", maxlen= 1024, default= "")
597
filepath = StringProperty(
600
filter_glob = StringProperty(
604
importmesh = BoolProperty(
606
description="Import mesh only. (not yet build.)",
609
importbone = BoolProperty(
611
description="Import bones only. Current not working yet",
614
importmultiuvtextures = BoolProperty(
615
name="Single UV Texture(s)",
616
description="Single or Multi uv textures",
619
bDebugLogPSK = BoolProperty(
620
name="Debug Log.txt",
621
description="Log the output of raw format. It will save in " \
622
"current file dir. Note this just for testing",
625
unrealbonesize = FloatProperty(
627
description="Bone Length from head to tail distance",
578
633
def execute(self, context):
579
getInputFilename(self.filepath)
634
bpy.types.Scene.unrealbonesize = self.unrealbonesize
635
getInputFilename(self,self.filepath,self.importmesh,self.importbone,self.bDebugLogPSK,self.importmultiuvtextures)
580
636
return {'FINISHED'}
582
638
def invoke(self, context, event):
583
639
wm = context.window_manager
584
wm.add_fileselect(self)
640
wm.fileselect_add(self)
585
641
return {'RUNNING_MODAL'}
643
class OBJECT_OT_PSKPath(bpy.types.Operator):
644
bl_idname = "object.pskpath"
645
bl_label = "PSK Path"
648
filepath = StringProperty(
651
filter_glob = StringProperty(
655
importmesh = BoolProperty(
657
description="Import mesh only. (not yet build.)",
660
importbone = BoolProperty(
662
description="Import bones only. Current not working yet",
665
importmultiuvtextures = BoolProperty(
666
name="Single UV Texture(s)",
667
description="Single or Multi uv textures",
670
bDebugLogPSK = BoolProperty(
671
name="Debug Log.txt",
672
description="Log the output of raw format. It will save in " \
673
"current file dir. Note this just for testing",
676
unrealbonesize = FloatProperty(
678
description="Bone Length from head to tail distance",
684
def execute(self, context):
685
#context.scene.importpskpath = self.properties.filepath
686
bpy.types.Scene.unrealbonesize = self.unrealbonesize
687
getInputFilename(self,self.filepath,self.importmesh,self.importbone,self.bDebugLogPSK,self.importmultiuvtextures)
690
def invoke(self, context, event):
691
#bpy.context.window_manager.fileselect_add(self)
692
wm = context.window_manager
693
wm.fileselect_add(self)
694
return {'RUNNING_MODAL'}
696
class OBJECT_OT_PSAPath(bpy.types.Operator):
697
bl_idname = "object.psapath"
698
bl_label = "PSA Path"
701
filepath = StringProperty(name="PSA File Path", description="Filepath used for importing the PSA file", maxlen= 1024, default= "")
702
filter_glob = StringProperty(
706
def execute(self, context):
707
#context.scene.importpsapath = self.properties.filepath
708
psaimport(self.filepath)
711
def invoke(self, context, event):
712
bpy.context.window_manager.fileselect_add(self)
713
return {'RUNNING_MODAL'}
715
class OBJECT_OT_Path(bpy.types.Operator):
716
bl_idname = "object.path"
717
bl_label = "MESH BUILD TEST"
719
# generic transform props
720
view_align = BoolProperty(
721
name="Align to View",
724
location = FloatVectorProperty(
726
subtype='TRANSLATION',
728
rotation = FloatVectorProperty(
732
def execute(self, context):
735
def invoke(self, context, event):
736
me = bpy.data.meshes.new("test")
737
obmade = bpy.data.objects.new("TestObject",me)
738
print("Create Simple Mesh")
739
bpy.data.scenes[0].objects.link(obmade)
740
for i in bpy.context.scene.objects: i.select = False #deselect all objects
742
bpy.context.scene.objects.active = obmade
744
verts = [(0,0,0),(2,0,0),(2,0,2)]
745
edges = [(0,1),(1,2),(2,0)]
747
faces.extend([(0,1,2,0)])
748
#me.vertices.add(len(verts))
750
me.vertices.add(len(verts))
751
me.tessfaces.add(len(faces))
752
for face in me.tessfaces:
755
me.vertices.foreach_set("co", unpack_list(verts))
756
me.tessfaces.foreach_set("vertices_raw", unpack_list(faces))
757
me.edges.add(len(edges))
758
me.edges.foreach_set("vertices", unpack_list(edges))
760
#print(len(me.tessfaces))
761
me.tessface_uv_textures.new("uvtexture")
762
#for uv in me.tessface_uv_textures:
764
#print(dir(uv.data[0]))
765
#print(dir(uv.data[0].uv1))
766
return {'RUNNING_MODAL'}
768
#import menu panel tool bar
769
class VIEW3D_PT_unrealimport_objectmode(bpy.types.Panel):
770
bl_space_type = "VIEW_3D"
771
bl_region_type = "TOOLS"
772
bl_label = "Import PSK/PSA"
775
def poll(cls, context):
776
return context.active_object
778
def draw(self, context):
782
row2 = layout.row(align=True)
783
row2.operator(OBJECT_OT_PSKPath.bl_idname)
784
row2.operator(OBJECT_OT_PSAPath.bl_idname)
785
row2.operator(OBJECT_OT_Path.bl_idname)
587
787
def menu_func(self, context):
588
788
self.layout.operator(IMPORT_OT_psk.bl_idname, text="Skeleton Mesh (.psk)")
791
bpy.utils.register_module(__name__)
592
792
bpy.types.INFO_MT_file_import.append(menu_func)
594
794
def unregister():
795
bpy.utils.unregister_module(__name__)
595
796
bpy.types.INFO_MT_file_import.remove(menu_func)
597
798
if __name__ == "__main__":