def parse_mesh(d): p = 0 while p < len(d): p, block_id, block_size = xray_utils.read_block(p, d) if block_id == 0x1000: mesh_version, p = u('H', d, p) elif block_id == 0x1001: mesh_name, p = xray_utils.parse_string_nul(d, p) elif block_id == 0x1002: mesh_flags, p = u('B', d, p) elif block_id == 0x1004: bbox, p = u('6f', d, p) elif block_id == 0x1005: vertices = parse_vertices(d[p:p + block_size]) p += block_size elif block_id == 0x1006: triangles = parse_indices(d[p:p + block_size]) p += block_size elif block_id == 0x1008: parse_uv_indices(d[p:p + block_size]) p += block_size elif block_id == 0x1009: parse_material_indices(d[p:p + block_size]) p += block_size elif block_id == 0x1010: (mesh_option_0, mesh_option_1), p = u('II', d, p) elif block_id == 0x1012: parse_uvs(d[p:p + block_size]) p += block_size elif block_id == 0x1013: smooth_groups, p = u('%dI' % (len(d[p:p + block_size]) // 4), d, p) else: print('! UNKNOW BLOCK 0x7777-0x0910-', hex(block_id), sep='') p += block_size return vertices, triangles
def parse_object(d): p, mainSz = 0, len(d) while p < mainSz: (id, sz), p = u('II', d, p) if id == 0x0900: (fmtVer, ), p = u('H', d, p) if fmtVer != 16: xray_utils.un_ver('OBJECT', fmtVer) break elif id == 0x0903: (flags, ), p = u('I', d, p) elif id == 0x0907: materials = parse_materials(d[p:p + sz]) p += sz elif id == 0x0910: verts, faces, materialIndices = parse_meshes(d[p:p + sz]) p += sz elif id == 0x0911: libVer, p = xray_utils.parse_date(d, p) (unk, ), p = u('I', d, p) elif id == 0x0912: userData, p = xray_utils.parse_string(d, p) elif id == 0x0922: author, p = xray_utils.parse_string(d, p) createDate, p = xray_utils.parse_date(d, p) modifer, p = xray_utils.parse_string(d, p) editDate, p = xray_utils.parse_date(d, p) elif id == 0x0925: lodReference, p = xray_utils.parse_string(d, p) else: xray_utils.un_blk(id) p += sz return verts, faces, materials, materialIndices
def parse_vertices(d): vertex_count, p = u('I', d, 0) vertices = [] for i in range(vertex_count): (loc_x, loc_y, loc_z), p = u('3f', d, p) vertices.append((loc_x, loc_z, loc_y)) return vertices
def parse_object(d): p = 0 while p < len(d): p, block_id, block_size = xray_utils.read_block(p, d) if block_id == 0x0900: format_version, p = u('H', d, p) elif block_id == 0x0903: flags, p = u('I', d, p) elif block_id == 0x0907: parse_materials(d[p:p + block_size]) p += block_size elif block_id == 0x0910: vertices, triangles = parse_meshes(d[p:p + block_size]) p += block_size elif block_id == 0x0912: user_data, p = xray_utils.parse_string_nul(d, p) elif block_id == 0x0922: author_name, p = xray_utils.parse_string_nul(d, p) create_date, p = xray_utils.parse_date(d, p) modifer_name, p = xray_utils.parse_string_nul(d, p) modifer_date, p = xray_utils.parse_date(d, p) elif block_id == 0x0925: lod_reference, p = xray_utils.parse_string_nul(d, p) else: print('! UNKNOW BLOCK 0x7777-', hex(block_id), sep='') p += block_size return vertices, triangles
def parse_indices(d): triangles_count, p = u('I', d, 0) triangles = [] for i in range(triangles_count): (vertex1, vertex2, vertex3, uv1, uv2, uv3), p = u('6I', d, p) triangles.append((vertex1, vertex3, vertex2)) return triangles
def parse_materials(d): material_count, p = u('I', d, 0) for i in range(material_count): material_name, p = xray_utils.parse_string_nul(d, p) engine_shader, p = xray_utils.parse_string_nul(d, p) compiler_shader, p = xray_utils.parse_string_nul(d, p) game_material, p = xray_utils.parse_string_nul(d, p) image_path, p = xray_utils.parse_string_nul(d, p) uv_map_name, p = xray_utils.parse_string_nul(d, p) (surface_flags, fvf, tc), p = u('III', d, p)
def parse_uvs(d): vmap_count, p = u('I', d, 0) for i in range(vmap_count): vmap_name, p = xray_utils.parse_string_nul(d, p) (value_dim, has_pidata, value_type), p = u('3B', d, p) data_count, p = u('I', d, p) for j in range(data_count): uv, p = u('2f', d, p) for j in range(data_count): unknow, p = u('I', d, p)
def parse_material_indices(d): ((matCnt, ), p), faceIndices = u('H', d, 0), [] for matIndex in range(matCnt): matName, p = xray_utils.parse_string(d, p) (tCnt, ), p = u('I', d, p) for i in range(tCnt): (faceIndex, ), p = u('I', d, p) faceIndices.append((faceIndex, matIndex)) faceIndices.sort() matIndices = [] for i in faceIndices: matIndices.append(i[1]) return matIndices
def parse_materials(d): ((matCnt, ), p), materials = u('I', d, 0), [] for i in range(matCnt): matName, p = xray_utils.parse_string(d, p) engine, p = xray_utils.parse_string(d, p) compiler, p = xray_utils.parse_string(d, p) material, p = xray_utils.parse_string(d, p) image, p = xray_utils.parse_string(d, p) uvMapName, p = xray_utils.parse_string(d, p) (flags, fvf, tc), p = u('III', d, p) materials.append(matName) materials = list(range(len(materials))) return materials
def parse_meshes(d): p, blkSz = 0, len(d) while p < blkSz: (id, sz), p = u('II', d, p) verts, faces, materialIndices = parse_mesh(d[p:p + sz]) p += sz return verts, faces, materialIndices
def parse_object(data): p = 0 dataSize = len(data) while p < dataSize: (chunkId, chunkCompress, chunkSize), p = u('HHI', data, p) if chunkId == 0x7777: parse_0x7777(data[p:p + chunkSize]) p += chunkSize
def parse_objects(data): p = 0 dataSize = len(data) while p < dataSize: (objectId, objectSize), p = u('II', data, p) dumpFile.write('\n[object_{0:0>4}]\n'.format(objectId)) parse_object(data[p:p + objectSize]) p += objectSize
def parse_detail_scale_limits(d): global dump ( minScale, maxScale, ), p = u('ff', d, 0) dump += ' min scale = {}\n'.format(round(minScale, 2)) dump += ' max scale = {}\n'.format(round(maxScale, 2))
def parse_meshes(d): _p, _blkSz = 0, len(d) newData = b'' while _p < _blkSz: newData += d[_p:_p + 8] (_id, _cmpr, _sz), _p = u('HHI', d, _p) newMesh = parse_dm.parse_main(d[_p:_p + _sz]) newData += newMesh _p += _sz return newData
def parse_meshes(d): p = 0 vertices, triangles = [], [] while p < len(d): (mesh_id, mesh_size), p = u('II', d, p) curent_vert, curent_faces = parse_mesh(d[p:p + mesh_size]) vertices.append(curent_vert) triangles.append(curent_faces) p += mesh_size return vertices, triangles
def parse_main(d): (id, cmpr, sz), p = u('HHI', d, 0) if id == 0x7777: verts, faces, materials, materialIndices = parse_object(d[p:p + sz]) meshData = {'verts': verts} meshData['faces'] = faces meshData['materials'] = materials meshData['material_indices'] = materialIndices return meshData else: xray_utils.un_blk(id)
def parse_color(d): global dump dump += '; colors\n\n' (colorCount, ), p = u('B', d, 0) for colorID in range(colorCount): dump += '[color_{0:0>2}]\n'.format(colorID) (B, G, R, unknow, referenceCount), p = u('5B', d, p) dump += ' rgb = {0}, {1}, {2}\n'.format(R, G, B) refList = [] for i in range(referenceCount): reference, p = xray_utils.parse_string(d, p) refList.append(reference) dump += ' references = ' refListSize = len(refList) for n, ref in enumerate(refList): if n != refListSize - 1: dump += '"{0}", '.format(ref) else: dump += '"{0}"\n\n'.format(ref) return colorCount
def parse_mesh(d): p, blkSz = 0, len(d) while p < blkSz: (id, sz), p = u('II', d, p) if id == 0x1000: (meshVer, ), p = u('H', d, p) elif id == 0x1001: meshName, p = xray_utils.parse_string(d, p) elif id == 0x1002: (flags, ), p = u('B', d, p) elif id == 0x1004: bBox, p = u('6f', d, p) elif id == 0x1005: ((vCnt, ), p), verts = u('I', d, p), [] for i in range(vCnt): (X, Y, Z), p = u('3f', d, p) verts.append((X, Z, Y)) if sz > vCnt * 12 + 4: # unknow data (balon_01.object) p += sz - vCnt * 12 - 4 elif id == 0x1006: ((tCnt, ), p), faces = u('I', d, p), [] for i in range(tCnt): (v1, uv1, v2, uv2, v3, uv3), p = u('6I', d, p) faces.append((v1, v3, v2)) elif id == 0x1008: parse_uv_indices(d[p:p + sz]) p += sz elif id == 0x1009: materialIndices = parse_material_indices(d[p:p + sz]) p += sz elif id == 0x1010: (option0, option1), p = u('II', d, p) elif id == 0x1012: parse_uvs(d[p:p + sz]) p += sz elif id == 0x1013: smthGrps, p = u('%dI' % (len(d[p:p + sz]) // 4), d, p) else: xray_utils.un_blk(id) p += sz return verts, faces, materialIndices
def parse_detail_objects(d): global dump dump += '; objects\n\n' p = 0 dataSize = len(d) objectCount = 0 while p < dataSize: (detId, detSize), p = u('II', d, p) dump += '[object_{0:0>2}]\n'.format(detId) objectCount += 1 parse_detail_object(d[p:p + detSize]) p += detSize return objectCount
def parse_main(d): _p, _fileSz = 0, len(d) newDet = open('level.details.new', 'wb') while _p < _fileSz: (_id, _cmpr, _sz), _p = u('HHI', d, _p) if _id == 0x1: newData = parse_meshes(d[_p:_p + _sz]) newDet.write(d[_p - 8:_p]) newDet.write(newData) else: newDet.write(d[_p - 8:_p + _sz]) _p += _sz newDet.close()
def parse_scene(data): p = 0 dataSize = len(data) while p < dataSize: (chunkId, chunkCompress, chunkSize), p = u('HHI', data, p) if chunkId == sceneObjectFmt['TAG']: authorName, p = xray_utils.parse_string(data, p) createDate, p = xray_utils.parse_date(data, p) dumpFile.write('author = \"{}\"\n'.format(authorName)) dumpFile.write('create_date = \"{}\"\n'.format(createDate)) elif chunkId == sceneObjectFmt['COUNT']: (objectCount, ), p = u('I', data, p) dumpFile.write('object_count = {}\n'.format(objectCount)) elif chunkId == sceneObjectFmt['OBJECTS']: parse_objects(data[p:p + chunkSize]) p += chunkSize elif chunkId == sceneObjectFmt['VERSION']: (version, ), p = u('H', data, p) dumpFile.write('\nversion = {}\n'.format(version)) elif chunkId == sceneObjectFmt['FLAGS']: (flags, ), p = u('I', data, p) dumpFile.write('flags = {}\n'.format(flags)) elif chunkId == sceneObjectFmt['PARAMS']: (minScaleX, minScaleY, minScaleZ, maxScaleX, maxScaleY, maxScaleZ, minRotX, minRotY, minRotZ, maxRotX, maxRotY, maxRotZ, snapObj), p = u('13f', data, p) dumpFile.write('min_scale = {0}, {1}, {2}\n'.format( minScaleX, minScaleY, minScaleZ)) dumpFile.write('max_scale = {0}, {1}, {2}\n'.format( maxScaleX, maxScaleY, maxScaleZ)) dumpFile.write('min_rotate = {0}, {1}, {2}\n'.format( minRotX, minRotY, minRotZ)) dumpFile.write('max_rotate = {0}, {1}, {2}\n'.format( maxRotX, maxRotY, maxRotZ)) dumpFile.write('snap_object = {0}\n'.format(snapObj)) else: xray_utils.un_blk(chunkId) p += chunkSize
def parse_main(data): global dump dataSize = len(data) envModCount = dataSize // 84 dump += '[modifers]\n' for i in range(envModCount): dump += ' modifer_{0:0>2}\n'.format(i) dump += '\n' p = 0 # position while p < dataSize: (id, size), p = u('II', data, p) dump += '[modifer_{0:0>2}]\n'.format(id) parse_environment_modificator(data[p : p + size]) p += size
def parse_main(d): scale = 2.0 newMesh = b'' shader, _p = xray_utils.parse_string(d, 0) image, _p = xray_utils.parse_string(d, _p) newMesh += d[0:_p + 4] (flgs, minS, maxS, vCnt, iCnt), _p = u('IffII', d, _p) newMinSize = struct.pack('f', minS * scale) newMaxSize = struct.pack('f', maxS * scale) newMesh += newMinSize + newMaxSize + d[_p - 8:] verts, uvs, faces = [], [], [] for _ in range(vCnt): (X, Y, Z, U, V), _p = u('5f', d, _p) verts.append((X, Z, Y)) uvs.append((U, 1 - V)) for _ in range(iCnt // 3): (v1, v2, v3), _p = u('3H', d, _p) faces.append((v1, v3, v2)) meshData = {'verts': verts} meshData['faces'] = faces meshData['uvs'] = uvs meshData['images'] = image return newMesh
def parse_main(d): p = 0 dataSize = len(d) while p < dataSize: (id, cmprs, size), p = u('HHI', d, p) cd = d[p:p + size] if id == DtiFormat.Chunks.Objects.id: objectCount = parse_detail_objects(cd) elif id == DtiFormat.Chunks.ColorIndex.id: colorCount = parse_color(cd) else: xray_utils.un_blk(id) p += size return objectCount, colorCount
def parse_environment_modificator(data): # SoC Format (posX, posY, posZ, radius, power, viewDistance, fogR, fogG, fogB, fogDensity, ambR, ambG, ambB, skyR, skyG, skyB, hemR, hemG, hemB), p = u('19f', data, 0) global dump dump += ' position = {:.6}, {:.6}, {:.6}\n'.format(posX, posY, posZ) dump += ' radius = {:.6}\n'.format(radius) dump += ' power = {:.6}\n'.format(power) dump += ' view_distance = {:.6}\n'.format(viewDistance) dump += ' fog_color = {:.6}, {:.6}, {:.6}\n'.format(fogR, fogG, fogB) dump += ' fog_density = {:.6}\n'.format(fogDensity) dump += ' ambient = {:.6}, {:.6}, {:.6}\n'.format(ambR, ambG, ambB) dump += ' sky_color = {:.6}, {:.6}, {:.6}\n'.format(skyR, skyG, skyB) dump += ' hemi_color = {:.6}, {:.6}, {:.6}\n\n'.format(hemR, hemG, hemB)
def parse_uvs(data): (count, ), p = u('I', data, 0) for _ in range(count): n, p = xray_utils.parse_string(data, p) (dim, ), p = u('B', data, p) (discon, ), p = u('B', data, p) (typ, ), p = u('B', data, p) typ = typ & 0x3 (sz, ), p = u('I', data, p) if typ == 0: uvs = [] vtx = [] for i in range(sz): uvs_cur, p = u('ff', data, p) uvs.append(uvs_cur) (vtx_cur, ), p = u('I', data, p) vtx.append(vtx_cur) if discon: fcs = [] for i in range(sz): (fcs_cur, ), p = u('I', data, p) fcs.append(fcs_cur)
def parse_detail_object(d): global dump p = 0 dataSize = len(d) while p < dataSize: (id, cmprs, sz), p = u('HHI', d, p) cd = d[p:p + sz] if id == DtiFormat.Chunks.Objects.Object.Version.id: parse_detail_version(cd) elif id == DtiFormat.Chunks.Objects.Object.Reference.id: parse_detail_reference(cd) elif id == DtiFormat.Chunks.Objects.Object.ScaleLimits.id: parse_detail_scale_limits(cd) elif id == DtiFormat.Chunks.Objects.Object.DensityFactor.id: parse_detail_density_factor(cd) elif id == DtiFormat.Chunks.Objects.Object.Flags.id: parse_detail_flags(cd) else: print('! unknow block {}'.format(hex(id))) p += sz dump += '\n'
def parse_0x7777(data): p = 0 dataSize = len(data) while p < dataSize: (chunkId, chunkCompress, chunkSize), p = u('HHI', data, p) if chunkId == 0x0900: (version, ), p = u('H', data, p) dumpFile.write('version = {}\n'.format(version)) elif chunkId == 0x0902: ( fileVersion, unknow, ), p = u('II', data, p) reference, p = xray_utils.parse_string(data, p) dumpFile.write('file_version = {}\n'.format(fileVersion)) dumpFile.write('reference = {}\n'.format(reference)) elif chunkId == 0x0905: (flags, ), p = u('I', data, p) dumpFile.write('flags = {}\n'.format(flags)) elif chunkId == 0xf903: (posX, pozY, posZ, rotX, rotY, rotZ, scaleX, scaleY, scaleZ), p = u('9f', data, p) dumpFile.write('position = {0}, {1}, {2}\n'.format( posX, pozY, posZ)) dumpFile.write('rotation = {0}, {1}, {2}\n'.format( rotX, rotY, rotZ)) dumpFile.write('scale = {0}, {1}, {2}\n'.format( scaleX, scaleY, scaleZ)) elif chunkId == 0xf906: (objectFlags, ), p = u('I', data, p) objectSelected = bool(objectFlags & 0b1) objectVisible = bool(objectFlags & 0b10) objectLocked = bool(objectFlags & 0b100) objectMotionable = bool(objectFlags & 0b1000) dumpFile.write('selected = {}\n' 'visible = {}\n' 'locked = {}\n' 'motionable = {}\n'.format( objectSelected, objectVisible, objectLocked, objectMotionable)) elif chunkId == 0xf907: objectName, p = xray_utils.parse_string(data, p) dumpFile.write('name = {}\n'.format(objectName)) else: xray_utils.un_blk(chunkId) p += chunkSize
def parse_mesh(d): meshSize = len(d) p = 0 while p < meshSize: (id, cmpr, sz), p = u('HHI', d, p) if id == 0x1000: meshVer, p = u('H', d, p) elif id == 0x1001: meshName, p = u('%ds' % sz, d, p) elif id == 0x1002: flags, p = u('B', d, p) elif id == 0x1003: unknow, p = u('B', d, p) elif id == 0x1004: bbox, p = u('6f', d, p) elif id == 0x1005: (vCnt,), p = u('I', d, p) for i in range(vCnt): (X, Y, Z), p = u('3f', d, p) for i in range(vCnt): unknow, p = u('7B', d, p) elif id == 0x1006: tCnt = sz // 12 for i in range(tCnt): (v1, v2, v3), p = u('3I', d, p) print(v1, v2, v3) p += 4 elif id == 0x1010: unknow, p = u('IHH', d, p) else: p += sz print(hex(id), sz)
unknow, p = u('7B', d, p) elif id == 0x1006: tCnt = sz // 12 for i in range(tCnt): (v1, v2, v3), p = u('3I', d, p) print(v1, v2, v3) p += 4 elif id == 0x1010: unknow, p = u('IHH', d, p) else: p += sz print(hex(id), sz) d = xray_utils.read_bin_file('Bush6_hang.object') (id, cmpr, sz), p = u('HHI', d, 0) fileSize = len(d) while p < fileSize: (id, cmpr, sz), p = u('HHI', d, p) if id == 0x0900: # format version (fmtVer,), p = u('H', d, p) elif id == 0x0903: objectType, p = u('B', d, p) elif id == 0x0904: # transformations (pX, pY, pZ, rX, rY, rZ, sX, sY, sZ), p = u('9f', d, p) elif id == 0x0905: (materialId,), p = u('I', d, p) materialName, p = xray_utils.parse_string(d, p) shader, p = xray_utils.parse_string(d, p) unknow, p = u('BBHHHB', d, p) texture, p = xray_utils.parse_string(d, p)