return i else: md.materials.append(mat) return len(md.materials) - 1 else: mat = bpy.data.materials.new(mat_name) mat.diffuse_color = [random.uniform(.4, 1) for _ in range(3)] + [1.0] md.materials.append(mat) return len(md.materials) - 1 file = r"D:\SteamLibrary\steamapps\common\ZombieArmy4\UNPACK\inst (static).model" mesh_name = Path(file).stem reader = ByteIO(file) vertices_count = reader.read_uint32() indices_count = reader.read_uint32() polygon_count = reader.read_uint32() meshes = [] vertices_dtype = np.dtype( [ ('pos', np.uint16, (3,)), ('minus_one', np.int16, (1,)), ("uv_0", np.float16, (2,)), ("uv_1", np.float16, (2,)), ("unk1", np.uint8, (2,)), ('normals', np.int16, (3,)),
def skip_handler(self, reader: ByteIO, header: ChunkHeader, output_directory: Path): reader.skip(header.size - 16)
def __init__(self, reader: ByteIO): (self.unk, self.unk1_count, self.unk2_count, self.unk3_zero, self.unk4_offset, self.unk5_zero, self.unk6_offset, self.unk7_start, self.unk8_count, self.unk9_zero) = reader.read_fmt('10i') self.offset = reader.read_fmt('3f') self.scale = reader.read_fmt('3f')
def __init__(self, reader: ByteIO): self.offset = reader.read_fmt('3f') self.unk = reader.read(52)
def __init__(self, reader: ByteIO): self.unk = reader.read_fmt('4I') self.unk2_vec3 = reader.read_fmt('3f') self.unk3 = reader.read_fmt('4I') self.unk4_vec2 = reader.read_fmt('2f') self.unk5, self.unk6_id, self.unk7 = reader.read_fmt('3I')
def __init__(self, reader: ByteIO): self.unk = reader.read(60)
(self.unk, self.unk1_count, self.unk2_count, self.unk3_zero, self.unk4_offset, self.unk5_zero, self.unk6_offset, self.unk7_start, self.unk8_count, self.unk9_zero) = reader.read_fmt('10i') self.offset = reader.read_fmt('3f') self.scale = reader.read_fmt('3f') class INST: def __init__(self, reader: ByteIO): self._reader = reader header = self.header = ChunkHeader(reader) pos_count = reader.read_uint32() self.pose_blocks = [PropPos(reader) for _ in range(pos_count)] block_count = reader.read_uint32() if header.version < 18: self.unk_v18 = reader.read_fmt('5I') if header.version in (15, 16): self.blocks = [BlockV15_V16(reader) for _ in range(block_count)] else: self.blocks = [BlockV18(reader) for _ in range(block_count)] block2_count = reader.read_uint32() self.blocks2 = [Block2(reader) for _ in range(block2_count)] if __name__ == '__main__': a = INST( ByteIO( r"D:\SteamLibrary\steamapps\common\ZombieArmy4\UNPACK\chunks\h_hellbase\INST\103c3832.chunk" )) print(a)
def __init__(self, reader: ByteIO): (self.key, self.unk_1, self.indices_count, self.unk_2, self.unk_3, self.unk_4) = reader.read_fmt('6I')
def import_model(model_path: Path, is_se3=False): assert model_path.exists(), f'Missing "{model_path}" file' skeleton_path = model_path.with_suffix('.skeleton') if skeleton_path.exists(): skeleton_reader = ByteIO(skeleton_path) hskn_file = HSKN(skeleton_reader) armature = create_armature(hskn_file) else: hskn_file = None armature = None mesh_reader = ByteIO(model_path) mesh_name = Path(model_path).stem model_file = Model(mesh_reader, is_se3) vertex_data = model_file.vertex_data pos = ((vertex_data['pos'] / 32767) * (model_file.scale / 2)) + model_file.offset / 2 normals = vertex_data['unk'].copy() / 32768 mesh_data = bpy.data.meshes.new(f'{mesh_name}_MESH') mesh_obj = bpy.data.objects.new(f'{mesh_name}', mesh_data) mesh_data.from_pydata(pos, [], model_file.indices.tolist()) mesh_data.update() if armature: modifier = mesh_obj.modifiers.new(type="ARMATURE", name="Armature") modifier.object = armature mesh_obj.parent = armature # offset = 0 material_indices_array = np.array([], dtype=np.uint32) for mesh in model_file.meshes: mesh_polygon_count = mesh.indices_count // 3 mat_name = f'{mesh.key:08X}' mat_id = get_material(mat_name, mesh_obj) material_indices_array = np.hstack( [material_indices_array, np.full(mesh_polygon_count, mat_id)]) # material_indices_array[offset:offset + mesh_polygon_count] = mat_id # offset += mesh_polygon_count mesh_data.polygons.foreach_set('material_index', material_indices_array.tolist()) vertex_indices = np.zeros((len(mesh_data.loops, )), dtype=np.uint32) mesh_data.loops.foreach_get('vertex_index', vertex_indices) uv_layer = mesh_data.uv_layers.new() uv_data = uv_layer.data uv_0 = vertex_data['uv_0'].copy() uv_0[:, 1] = 1 - uv_0[:, 1] uv_data.foreach_set('uv', uv_0[vertex_indices].flatten()) uv_layer = mesh_data.uv_layers.new() uv_data = uv_layer.data uv_1 = vertex_data['uv_1'].copy() uv_1[:, 1] = 1 - uv_0[:, 1] uv_data.foreach_set('uv', uv_1[vertex_indices].flatten()) # mesh_data.polygons.foreach_set("use_smooth", np.ones(len(mesh_data.polygons))) # mesh_data.normals_split_custom_set_from_vertices(normals) # mesh_data.use_auto_smooth = True if hskn_file: bone_names = {n: bone.name for (n, bone) in enumerate(hskn_file.bones)} else: bone_names = { a: f"bone_{a}" for a in np.unique(vertex_data['bone_ids']) } weight_groups = { bone: mesh_obj.vertex_groups.new(name=bone) for bone in bone_names.values() } for n, (bone_indices, bone_weights) in enumerate( zip(vertex_data['bone_ids'], vertex_data['weights'] / 255)): for bone_index, weight in zip(bone_indices, bone_weights): if weight > 0.0: weight_groups[bone_names[bone_index]].add([n], weight, 'REPLACE') bpy.context.scene.collection.objects.link(mesh_obj)