def load_materialcollection(ovl_data, matcol_file_path, sized_str_entry): matcol_data = MatcolFile() matcol_data.load(matcol_file_path) if sized_str_entry.has_texture_list_frag: pointers = [tex_frag.pointers[1] for tex_frag in sized_str_entry.tex_frags] new_names = [n for t in matcol_data.texture_wrapper.textures for n in (t.fgm_name, t.texture_suffix, t.texture_type)] else: pointers = [] new_names = [] if sized_str_entry.is_variant: for (m0,), variant in zip(sized_str_entry.mat_frags, matcol_data.variant_wrapper.materials): # print(layer.name) pointers.append(m0.pointers[1]) new_names.append(variant) elif sized_str_entry.is_layered: for (m0, info, attrib), layer in zip(sized_str_entry.mat_frags, matcol_data.layered_wrapper.layers): # print(layer.name) pointers.append(m0.pointers[1]) new_names.append(layer.name) for frag, wrapper in zip(info.children, layer.infos): frag.pointers[0].update_data(as_bytes(wrapper.info), update_copies=True) frag.pointers[1].update_data(as_bytes(wrapper.name), update_copies=True) pointers.append(frag.pointers[1]) new_names.append(wrapper.name) for frag, wrapper in zip(attrib.children, layer.attribs): frag.pointers[0].update_data(as_bytes(wrapper.attrib), update_copies=True) frag.pointers[1].update_data(as_bytes(wrapper.name), update_copies=True) pointers.append(frag.pointers[1]) new_names.append(wrapper.name) update_matcol_pointers(pointers, new_names)
def load_fgm(ovl_data, fgm_file_path, fgm_sized_str_entry): fgm_data = FgmFile() fgm_data.load(fgm_file_path) sizedstr_bytes = as_bytes(fgm_data.fgm_info) + as_bytes( fgm_data.two_frags_pad) # todo - move texpad into fragment padding? textures_bytes = as_bytes(fgm_data.textures) + as_bytes(fgm_data.texpad) attributes_bytes = as_bytes(fgm_data.attributes) # the actual injection fgm_sized_str_entry.data_entry.update_data((fgm_data.buffer_bytes, )) fgm_sized_str_entry.pointers[0].update_data(sizedstr_bytes, update_copies=True) if len(fgm_sized_str_entry.fragments) == 4: datas = (textures_bytes, attributes_bytes, fgm_data.zeros_bytes, fgm_data.data_bytes) # fgms without zeros elif len(fgm_sized_str_entry.fragments) == 3: datas = (textures_bytes, attributes_bytes, fgm_data.data_bytes) # fgms for variants elif len(fgm_sized_str_entry.fragments) == 2: datas = (attributes_bytes, fgm_data.data_bytes) else: raise AttributeError("Unexpected fgm frag count") # inject fragment datas for frag, data in zip(fgm_sized_str_entry.fragments, datas): frag.pointers[1].update_data(data, update_copies=True)
def update_entry(self): # overwrite mdl2 modeldata frags for frag, modeldata in zip(self.mdl2_entry.model_data_frags, self.models): frag_data = as_bytes(modeldata, version_info=self.versions) frag.pointers[0].update_data(frag_data, update_copies=True) if len(self.lods) > 0: self.lodinfo = as_bytes(self.lods, version_info=self.versions) # overwrite mdl2 lodinfo frag self.mdl2_entry.fragments[1].pointers[1].update_data(self.lodinfo, update_copies=True)
def update_entry(self): print(f"Updating {self}") # write each model's vert & tri block to a temporary buffer temp_vert_writer = io.BytesIO() temp_tris_writer = io.BytesIO() # set initial offset for the first modeldata vert_offset = 0 tris_offset = 0 # go over all input mdl2 files for mdl2 in self.mdl2s: print(f"Flushing {mdl2}") # read the mdl2 for model in mdl2.models: print( f"Vertex Offset: {vert_offset}, Tris Offset: {tris_offset}" ) # write buffer to each output temp_vert_writer.write(model.verts_bytes) temp_tris_writer.write(model.tris_bytes) # update mdl2 offset values model.vertex_offset = vert_offset model.tri_offset = tris_offset # get offsets for the next model vert_offset = temp_vert_writer.tell() tris_offset = temp_tris_writer.tell() # get bytes from IO object vert_bytes = temp_vert_writer.getvalue() tris_bytes = temp_tris_writer.getvalue() buffers = self.ms2_entry.data_entry.buffer_datas[:1] buffers.append(self.bone_info) buffers.append(vert_bytes + tris_bytes) # modify buffer size self.buffer_info.vertexdatasize = len(vert_bytes) self.buffer_info.facesdatasize = len(tris_bytes) # overwrite ms2 buffer info frag buffer_info_frag = self.ms2_entry.fragments[0] buffer_info_frag.pointers[1].update_data(as_bytes( self.buffer_info, version_info=self.versions), update_copies=True) # update data self.ms2_entry.data_entry.update_data(buffers) # also flush the mdl2s for mdl2 in self.mdl2s: mdl2.update_entry()