|
| 1 | +import bpy,os |
| 2 | +import Blender,struct |
| 3 | +from Blender import * |
| 4 | +from struct import * |
| 5 | +import zlib |
| 6 | +from Blender.Mathutils import * |
| 7 | +from myFunction import * |
| 8 | + |
| 9 | +#Blender 2.70 python experimental script for importing models from Sleeping Dogs PC game |
| 10 | +#install python 3.4 |
| 11 | +#unpack 'CharactersHD.big' from game with SDBIGUnpacker.exe (www.xentax.com,www.google) |
| 12 | +#run script with alt+p |
| 13 | +#select *.perm.bin file |
| 14 | +#it work for autotexturing and weighting |
| 15 | +#no bones |
| 16 | +#script is free |
| 17 | + |
| 18 | +def ddsheader(): |
| 19 | + ddsheader = '\x44\x44\x53\x20\x7C\x00\x00\x00\x07\x10\x0A\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x0B\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x05\x00\x00\x00\x44\x58\x54\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x10\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' |
| 20 | + return ddsheader |
| 21 | + |
| 22 | + |
| 23 | +def dds(dxt,compress): |
| 24 | + new=open(model_dir+os.sep+newname+'.dds','wb') |
| 25 | + new.write(ddsheader()) |
| 26 | + new.seek(0xC) |
| 27 | + new.write(hh) |
| 28 | + new.seek(0x10) |
| 29 | + new.write(w) |
| 30 | + new.seek(0x54) |
| 31 | + new.write(dxt) |
| 32 | + new.seek(128) |
| 33 | + if compress==1: |
| 34 | + zdata=zlib.decompress(plik.read(what[m][3])) |
| 35 | + else: |
| 36 | + zdata=plik.read(what[m][3]) |
| 37 | + new.write(zdata) |
| 38 | + new.close() |
| 39 | + print(plik.tell()) |
| 40 | + |
| 41 | + |
| 42 | +def bin_parser(filename): |
| 43 | + |
| 44 | + tempfile=None |
| 45 | + |
| 46 | + g.debug=False#True |
| 47 | + |
| 48 | + streams={} |
| 49 | + materials={} |
| 50 | + streamsID=[] |
| 51 | + mesh_list=[] |
| 52 | + meshID=0 |
| 53 | + bonenamelist=[] |
| 54 | + |
| 55 | + while(True): |
| 56 | + if g.tell()==g.fileSize():break |
| 57 | + vm=g.i(4) |
| 58 | + t=g.tell() |
| 59 | + g.seek(vm[3],1) |
| 60 | + vc=g.i(7) |
| 61 | + g.word(36) |
| 62 | + if vm[0]==-1742448933: |
| 63 | + vn=g.i(8) |
| 64 | + g.B(160) |
| 65 | + for m in range(vn[1]): |
| 66 | + bonenamelist.append(g.word(64)) |
| 67 | + for m in range(vn[1]): |
| 68 | + v1=g.H(1)[0]*2**-14 |
| 69 | + v2=g.H(1)[0]*2**-14 |
| 70 | + v3=g.H(1)[0]*2**-14 |
| 71 | + v4=g.H(1)[0]*2**-14 |
| 72 | + print(v1,v2,v3,v4) |
| 73 | + |
| 74 | + if vm[0]==-843079536:#texture |
| 75 | + tempfile=open(filename.replace('.perm.','.temp.'),'rb') |
| 76 | + temp=BinaryReader(tempfile) |
| 77 | + vn=g.i(55) |
| 78 | + w,h,dxt=None,None,None |
| 79 | + if vn[4]==65546: |
| 80 | + w,h=2048,2048 |
| 81 | + if vn[4]==65545: |
| 82 | + w,h=1024,1024 |
| 83 | + if vn[4]==65544: |
| 84 | + w,h=512,512 |
| 85 | + if vn[4]==65543: |
| 86 | + w,h=256,256 |
| 87 | + if vn[4]==65542: |
| 88 | + w,h=128,128 |
| 89 | + if vn[4]==65542: |
| 90 | + w,h=64,64 |
| 91 | + if vn[1]==1: |
| 92 | + dxt='DXT1' |
| 93 | + if vn[1]==3: |
| 94 | + dxt='DXT5' |
| 95 | + if vn[1]==2: |
| 96 | + dxt='DXT3' |
| 97 | + |
| 98 | + if w!=None: |
| 99 | + new=open(dirname+os.sep+str(vc[3])+'.dds','wb') |
| 100 | + new.write(ddsheader()) |
| 101 | + new.seek(0xC) |
| 102 | + new.write(struct.pack('i',w)) |
| 103 | + new.seek(0x10) |
| 104 | + new.write(struct.pack('i',h)) |
| 105 | + new.seek(0x54) |
| 106 | + new.write(dxt) |
| 107 | + new.seek(128) |
| 108 | + |
| 109 | + tempfile.seek(vn[12]) |
| 110 | + new.write(tempfile.read(vn[13])) |
| 111 | + new.close() |
| 112 | + tempfile.close() |
| 113 | + |
| 114 | + |
| 115 | + if vm[0]==1845060531:#meshes info section |
| 116 | + |
| 117 | + g.tell() |
| 118 | + vn=g.i(15) |
| 119 | + vn=g.i(17) |
| 120 | + off=g.tell() |
| 121 | + offsetlist=g.i(vn[1]) |
| 122 | + for m in range(vn[1]): |
| 123 | + g.seek(m*4+off+offsetlist[m]) |
| 124 | + va=g.i(36) |
| 125 | + if str(va[11]) in streams: |
| 126 | + materialID=va[3] |
| 127 | + material=Facesgroups() |
| 128 | + material.name=str(model_id)+'-mat-'+str(m) |
| 129 | + try:material.diffuse=dirname+os.sep+str(materials[str(materialID)]['diffID'])+'.dds' |
| 130 | + except:pass |
| 131 | + if va[15] not in streamsID: |
| 132 | + streamsID.append(va[15]) |
| 133 | + mesh=Mesh() |
| 134 | + mesh.name=str(model_id)+'-model-'+str(meshID) |
| 135 | + #mesh.BINDSKELETON=True |
| 136 | + mesh.TRIANGLE=True |
| 137 | + mesh_list.append(mesh) |
| 138 | + meshID+=1 |
| 139 | + mesh=mesh_list[streamsID.index(va[15])] |
| 140 | + |
| 141 | + #go to indices stream |
| 142 | + print(va[11]) |
| 143 | + indicesstream=streams[str(va[11])] |
| 144 | + g.seek(indicesstream[1]) |
| 145 | + mesh.indiceslist.extend(g.h(indicesstream[0][4])[va[29]:va[29]+va[30]*3]) |
| 146 | + print(len(mesh.indiceslist)/3-va[30],va[30],indicesstream[1]) |
| 147 | + material.faceIDstart=len(mesh.indiceslist)/3-va[30] |
| 148 | + material.faceIDcount=va[30] |
| 149 | + mesh.facesgroupslist.append(material) |
| 150 | + |
| 151 | + #go to uv stream |
| 152 | + if str(va[23]) in streams: |
| 153 | + uvstream=streams[str(va[23])] |
| 154 | + g.seek(uvstream[1]) |
| 155 | + for n in range(uvstream[0][4]): |
| 156 | + tn=g.tell() |
| 157 | + mesh.vertexuvlist.append(g.half(2)) |
| 158 | + g.seek(tn+uvstream[0][3]) |
| 159 | + |
| 160 | + #go to skin stream |
| 161 | + if str(va[19]) in streams: |
| 162 | + vertexgroups=Vertexgroups() |
| 163 | + skinstream=streams[str(va[19])] |
| 164 | + print('skin',skinstream) |
| 165 | + g.seek(skinstream[1]) |
| 166 | + vertexgroups.vertexIDstart=len(mesh.vertexlist) |
| 167 | + vertexgroups.vertexIDcount=skinstream[0][4] |
| 168 | + for n in range(skinstream[0][4]): |
| 169 | + tn=g.tell() |
| 170 | + vertexgroups.indiceslist.append(g.B(4)) |
| 171 | + w1=g.B(1)[0]/255.0 |
| 172 | + w2=g.B(1)[0]/255.0 |
| 173 | + w3=g.B(1)[0]/255.0 |
| 174 | + w4=g.B(1)[0]/255.0 |
| 175 | + vertexgroups.weightslist.append([w1,w2,w3,w4]) |
| 176 | + g.seek(tn+skinstream[0][3]) |
| 177 | + vertexgroups.usedbones=bonenamelist |
| 178 | + mesh.vertexgroupslist.append(vertexgroups) |
| 179 | + |
| 180 | + #go to vertex position stream |
| 181 | + print('vertexstream',va[15]) |
| 182 | + vertexstream=streams[str(va[15])] |
| 183 | + g.seek(vertexstream[1]) |
| 184 | + g.debug=False |
| 185 | + if vertexstream[0][3]==16: |
| 186 | + for n in range(vertexstream[0][4]): |
| 187 | + tn=g.tell() |
| 188 | + x=g.h(1)[0]*2**-14 |
| 189 | + y=g.h(1)[0]*2**-14 |
| 190 | + z=g.h(1)[0]*2**-14 |
| 191 | + mesh.vertexlist.append([x,y,z]) |
| 192 | + g.seek(tn+vertexstream[0][3]) |
| 193 | + if vertexstream[0][3]==12: |
| 194 | + for n in range(vertexstream[0][4]): |
| 195 | + tn=g.tell() |
| 196 | + mesh.vertexlist.append(g.f(3)) |
| 197 | + g.seek(tn+vertexstream[0][3]) |
| 198 | + |
| 199 | + #g.debug=True |
| 200 | + #break |
| 201 | + |
| 202 | + |
| 203 | + if vm[0]==-168275601:#material section |
| 204 | + #g.debug=False |
| 205 | + materials[str(vc[3])]={} |
| 206 | + g.tell() |
| 207 | + vn=g.i(8) |
| 208 | + for m in range(vn[4]): |
| 209 | + vp=g.i(8) |
| 210 | + if vp[0]==-589273463: |
| 211 | + materials[str(vc[3])]['diffID']=vp[6] |
| 212 | + if vp[0]==-1396934011: |
| 213 | + materials[str(vc[3])]['specID']=vp[6] |
| 214 | + g.i(4) |
| 215 | + #g.debug=True |
| 216 | + |
| 217 | + if vm[0]==2056721529:#streams section:vertex position,vertex uv,vertex indices,vertex skin |
| 218 | + v=g.i(32) |
| 219 | + streams[str(vc[3])]=[v,g.tell()] |
| 220 | + g.seek(t+vm[1]) |
| 221 | + g.tell() |
| 222 | + |
| 223 | + for mesh in mesh_list: |
| 224 | + mesh.draw() |
| 225 | + |
| 226 | + |
| 227 | +def file_format_parser(filename): |
| 228 | + print() |
| 229 | + print(filename) |
| 230 | + print() |
| 231 | + global g,model_id,txt,text,dirname |
| 232 | + global skeleton,used_bones |
| 233 | + skeleton=None |
| 234 | + used_bones=None |
| 235 | + |
| 236 | + |
| 237 | + |
| 238 | + model_id=create_object_name() |
| 239 | + dirname=sys.dirname(filename) |
| 240 | + ext=filename.split('.')[-1].lower() |
| 241 | + |
| 242 | + if ext=='bin': |
| 243 | + file=open(filename,'rb') |
| 244 | + g=BinaryReader(file) |
| 245 | + #g.logfile=open(filename+'.log','w') |
| 246 | + #g.log=True |
| 247 | + bin_parser(filename) |
| 248 | + file.close() |
| 249 | + #g.logfile.close() |
| 250 | + |
| 251 | +Window.FileSelector(file_format_parser) |
0 commit comments