Пример #1
0
                    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,)),
Пример #2
0
 def skip_handler(self, reader: ByteIO, header: ChunkHeader,
                  output_directory: Path):
     reader.skip(header.size - 16)
Пример #3
0
 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')
Пример #4
0
 def __init__(self, reader: ByteIO):
     self.offset = reader.read_fmt('3f')
     self.unk = reader.read(52)
Пример #5
0
 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')
Пример #6
0
 def __init__(self, reader: ByteIO):
     self.unk = reader.read(60)
Пример #7
0
        (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)
Пример #8
0
 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')
Пример #9
0
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)