def export_fakes(py_ubi_forge, file_id): data = py_ubi_forge.temp_files(file_id) if data is None: py_ubi_forge.log.warn(__name__, "Failed to find file {:016X}".format(file_id)) return model_name = data['fileName'] files = data['rawFile'].split( b'\x00\x00\x00\x00\x00\x00\x00\x00\x24\xB5\x7F\xD7')[1:] obj_handler = mesh.ObjMtl(py_ubi_forge, model_name) for n in files: if b'\x29\x8D\x65\xEC' not in n: continue transformation_matrix = numpy.fromstring(n[15:79], numpy.float32).reshape(4, 4) visualLoc = n.find(b'\x29\x8D\x65\xEC') model_file_id = uint64(n[visualLoc + 8:visualLoc + 16]) model = py_ubi_forge.game_functions.read_model(py_ubi_forge, model_file_id) if model is not None: model.vertices = numpy.matmul( numpy.pad(model.vertices, ((0, 0), (0, 1)), 'constant', constant_values=1), transformation_matrix)[:, :3] obj_handler.export(model) obj_handler.save_and_close() py_ubi_forge.log.info(__name__, 'Exported {:016X}'.format(file_id))
def run(self, file_id: Union[str, int], forge_file_name: str, datafile_id: int, options: Union[List[dict], None] = None): if options is not None: self._options = options # should do some validation here # TODO add select directory option save_folder = pyUbiForge.CONFIG.get('dumpFolder', 'output') data = pyUbiForge.temp_files(file_id, forge_file_name, datafile_id) if data is None: logging.warning(f"Failed to find file {file_id:016X}") return data_block_name = data.file_name data_block: DataBlock = pyUbiForge.read_file(data.file) if self._options[0]["Export Method"] == 'Wavefront (.obj)': obj_handler = mesh.ObjMtl(data_block_name, save_folder) for data_block_entry_id in data_block.files: data = pyUbiForge.temp_files(data_block_entry_id) if data is None: logging.warning(f"Failed to find file {data_block_entry_id:016X}") continue if data.file_type in ('0984415E', '3F742D26'): # entity and entity group entity: Entity = pyUbiForge.read_file(data.file) if entity is None: logging.warning(f"Failed reading file {data.file_name} {data.file_id:016X}") continue for nested_file in entity.nested_files: if nested_file.file_type == 'EC658D29': # visual nested_file: Visual if '01437462' in nested_file.nested_files.keys(): # LOD selector lod_selector: LODSelector = nested_file.nested_files['01437462'] mesh_instance_data: MeshInstanceData = lod_selector.lod[self._options[0]['LOD']] elif '536E963B' in nested_file.nested_files.keys(): # Mesh instance mesh_instance_data: MeshInstanceData = nested_file.nested_files['536E963B'] else: logging.warning(f"Could not find mesh instance data for {data.file_name} {data.file_id:016X}") continue if mesh_instance_data is None: logging.warning(f"Failed to find file {data.file_name}") continue model_data = pyUbiForge.temp_files(mesh_instance_data.mesh_id) if model_data is None: logging.warning(f"Failed to find file {mesh_instance_data.mesh_id:016X}") continue model: mesh.BaseModel = pyUbiForge.read_file(model_data.file) if model is None or model.vertices is None: logging.warning(f"Failed reading model file {model_data.file_name} {model_data.file_id:016X}") continue transform = entity.transformation_matrix if len(mesh_instance_data.transformation_matrix) == 0: obj_handler.export(model, model_data.file_name, transform) else: for trm in mesh_instance_data.transformation_matrix: obj_handler.export(model, model_data.file_name, numpy.matmul(transform, trm)) logging.info(f'Exported {model_data.file_name}') else: logging.info(f'File type "{data.file_type}" is not currently supported. It has been skipped') obj_handler.save_and_close() logging.info(f'Finished exporting {data_block_name}.obj')
def run(self, file_id: Union[str, int], forge_file_name: str, datafile_id: int, options: Union[List[dict], None] = None): if options is not None: self._options = options # should do some validation here # TODO add select directory option save_folder = pyUbiForge.CONFIG.get('dumpFolder', 'output') data = pyUbiForge.temp_files(file_id, forge_file_name, datafile_id) if data is None: logging.warning(f"Failed to find file {file_id:016X}") return model_name = data.file_name if self._options[0]["Export Method"] == 'Wavefront (.obj)': model: mesh.BaseModel = pyUbiForge.read_file(data.file) if model is not None: obj_handler = mesh.ObjMtl(model_name, save_folder) obj_handler.export(model, model_name) obj_handler.save_and_close() logging.info(f'Exported {file_id:016X}') else: logging.warning(f'Failed to export {file_id:016X}') elif self._options[0]["Export Method"] == 'Collada (.dae)': obj_handler = mesh.Collada(model_name, save_folder) obj_handler.export(file_id, forge_file_name, datafile_id) obj_handler.save_and_close() logging.info(f'Exported {file_id:016X}') elif self._options[0]["Export Method"] == 'Send to Blender (experimental)': model: mesh.BaseModel = pyUbiForge.read_file(data.file) if model is not None: c = Client(('localhost', 6163)) cols = [Image.new('RGB', (1024, 1024), (128, 0, 0)) for _ in range(len(model.bones))] r = 5 for mesh_index, m in enumerate(model.meshes): c.send({ 'type': 'MESH', 'verts': tuple(tuple(vert) for vert in model.vertices), 'faces': tuple(tuple(face) for face in model.faces[mesh_index][:m['face_count']]) }) for vtx in model.vert_table: x, y = vtx['vt'].astype(numpy.float) / 2 for index, bone_index in enumerate(vtx['bn']): if vtx['bw'][index] > 0: draw = ImageDraw.Draw(cols[bone_index]) draw.ellipse((x - r, y - r, x + r, y + r), fill=(vtx['bw'][index], vtx['bw'][index], vtx['bw'][index])) for index, im in enumerate(cols): im.save(f'{save_folder}/{model_name}_{index}.png') print(f'saved {save_folder}/{model_name}_{index}.png') c.send({ 'type': 'BONES', 'bone_id': [bone.bone_id for bone in model.bones], 'mat': [bone.transformation_matrix for bone in model.bones], })
def plugin(py_ubi_forge, file_id, forge_file_name, datafile_id, options): # TODO add select directory option save_folder = py_ubi_forge.CONFIG['dumpFolder'] data = py_ubi_forge.temp_files(file_id, forge_file_name, datafile_id) if data is None: py_ubi_forge.log.warn(__name__, f"Failed to find file {file_id:016X}") return model_name = data.file_name model = py_ubi_forge.read_file(data.file) if model is not None: obj_handler = mesh.ObjMtl(py_ubi_forge, model_name, save_folder) obj_handler.export(model, model_name) obj_handler.save_and_close() py_ubi_forge.log.info(__name__, f'Exported {file_id:016X}') else: py_ubi_forge.log.warn(__name__, f'Failed to export {file_id:016X}')
def run(self, py_ubi_forge, file_id: Union[str, int], forge_file_name: str, datafile_id: int, options: Union[List[dict], None] = None): if options is not None: self._options = options # should do some validation here # TODO add select directory option save_folder = py_ubi_forge.CONFIG.get('dumpFolder', 'output') data = py_ubi_forge.temp_files(file_id, forge_file_name, datafile_id) if data is None: py_ubi_forge.log.warn(__name__, f"Failed to find file {file_id:016X}") return fakes_name = data.file_name fakes: Fakes = py_ubi_forge.read_file(data.file) if self._options[0]["Export Method"] == 'Wavefront (.obj)': obj_handler = mesh.ObjMtl(py_ubi_forge, fakes_name, save_folder) for fake in fakes.fakes + fakes.near_fakes: entity = fake.entity if entity is None: py_ubi_forge.log.warn( __name__, f"Failed reading file {data.file_name} {data.file_id:016X}" ) continue for nested_file in entity.nested_files: if nested_file.file_type == 'EC658D29': # visual nested_file: Visual if '01437462' in nested_file.nested_files.keys( ): # LOD selector lod_selector: LODSelector = nested_file.nested_files[ '01437462'] mesh_instance_data: MeshInstanceData = lod_selector.lod[ 0] elif '536E963B' in nested_file.nested_files.keys( ): # Mesh instance mesh_instance_data: MeshInstanceData = nested_file.nested_files[ '536E963B'] else: py_ubi_forge.log.warn( __name__, f"Could not find mesh instance data for {data.file_name} {data.file_id:016X}" ) continue if mesh_instance_data is None: py_ubi_forge.log.warn( __name__, f"Failed to find file {data.file_name}") continue model_data = py_ubi_forge.temp_files( mesh_instance_data.mesh_id) if model_data is None: py_ubi_forge.log.warn( __name__, f"Failed to find file {mesh_instance_data.mesh_id:016X}" ) continue model: mesh.BaseModel = py_ubi_forge.read_file( model_data.file) if model is None or model.vertices is None: py_ubi_forge.log.warn( __name__, f"Failed reading model file {model_data.file_name} {model_data.file_id:016X}" ) continue transform = entity.transformation_matrix if len(mesh_instance_data.transformation_matrix) == 0: obj_handler.export(model, model_data.file_name, transform) else: for trm in mesh_instance_data.transformation_matrix: obj_handler.export( model, model_data.file_name, numpy.matmul(transform, trm)) py_ubi_forge.log.info( __name__, f'Exported {model_data.file_name}') obj_handler.save_and_close() py_ubi_forge.log.info(__name__, f'Finished exporting {fakes_name}.obj')