Пример #1
0
def test_mod_bones_array(mods_from_arc):
    for mod in mods_from_arc:
        if mod.bone_count:
            assert len(mod.bones_array) == mod.bone_count
            assert get_offset(mod, 'bones_array') == mod.bones_array_offset
        else:
            assert mod.bones_array_offset == 0
Пример #2
0
def test_vertex_buffer(mods_from_arc):
    for mod in mods_from_arc:
        assert get_offset(mod, 'vertex_buffer') == mod.vertex_buffer_offset
Пример #3
0
def test_meshes_array_2(mods_from_arc):
    for mod in mods_from_arc:
        assert get_offset(mod, 'meshes_array_2') == get_offset(mod, 'meshes_array') + get_size(mod, 'meshes_array')
        assert get_offset(mod, 'vertex_buffer') == get_offset(mod, 'meshes_array_2') + get_size(mod, 'meshes_array_2')
Пример #4
0
def test_mod_textures_array_offset(mods_from_arc):
    for mod in mods_from_arc:
        if mod.texture_count or mod.material_count:
            assert mod.textures_array_offset > get_offset(mod, 'group_data_array')
        else:
            assert mod.textures_array_offset == 0
Пример #5
0
def test_mod_bones_array_offset(mods_from_arc):
    for mod in mods_from_arc:
        if mod.bone_count:
            assert mod.bones_array_offset >= get_offset(mod, 'unk_12')
        else:
            assert mod.bones_array_offset == 0
Пример #6
0
def export_mod156(parent_blender_object):
    '''The blender_object provided should have meshes as children'''
    try:
        saved_mod = Mod156(
            file_path=BytesIO(parent_blender_object.albam_imported_item.data))
    except AttributeError:
        raise ExportError(
            "Can't export '{0}' to Mod156, the model to be exported "
            "wasn't imported using Albam".format(parent_blender_object.name))

    children_objects = [child for child in parent_blender_object.children]
    empty_children = [c for c in children_objects if c.type == 'EMPTY']
    meshes_children = [c for c in children_objects if c.type == 'MESH']
    bounding_box = get_bounding_box_positions_from_blender_objects(
        children_objects)

    if len(meshes_children) < len(saved_mod.meshes_array) and empty_children:
        # There were failed meshes that were replaced as empties in the import
        # We need to remove the extra weight groups (or whaterver they are),
        # before exporting
        failed_indices = {
            i
            for i, obj in enumerate(parent_blender_object.children)
            if obj.type == 'EMPTY'
        }
        new_bytes = []
        current_position = 0
        for i, mesh in enumerate(saved_mod.meshes_array):
            size = 144 * mesh.vertex_group_count
            data = saved_mod.meshes_array_2[current_position:current_position +
                                            size]
            current_position = current_position + size
            if i in failed_indices:
                continue
            else:
                new_bytes.extend(data)
        # the misterious extra 4 bytes for mod.156
        new_bytes.extend(saved_mod.meshes_array_2[-4:])
        meshes_array_2 = (ctypes.c_ubyte * len(new_bytes))(*new_bytes)
    elif len(meshes_children) != len(
            saved_mod.meshes_array) and not empty_children:
        raise ExportError(
            "Can't import {0}, different meshes quantity ({1} vs {2}) "
            "Support for this will come soon".format(
                parent_blender_object.name, len(saved_mod.meshes_array),
                len(children_objects)))
    else:
        meshes_array_2 = saved_mod.meshes_array_2

    textures_array, materials_array = _export_textures_and_materials(
        children_objects, saved_mod)
    meshes_array, vertex_buffer, index_buffer = _export_meshes(
        children_objects, bounding_box, saved_mod)

    bone_count = get_bone_count_from_blender_objects([parent_blender_object])
    if not bone_count:
        bones_array_offset = 0
    elif bone_count and saved_mod.unk_08:
        bones_array_offset = 176 + len(saved_mod.unk_12)
    else:
        bones_array_offset = 176

    mod = Mod156(
        id_magic=b'MOD',
        version=156,
        version_rev=1,
        bone_count=bone_count,
        mesh_count=get_mesh_count_from_blender_objects(children_objects),
        material_count=len(materials_array),
        vertex_count=get_vertex_count_from_blender_objects(children_objects),
        face_count=(ctypes.sizeof(index_buffer) // 2) + 1,
        edge_count=0,  # TODO: add edge_count
        vertex_buffer_size=ctypes.sizeof(vertex_buffer),
        vertex_buffer_2_size=len(saved_mod.vertex_buffer_2),
        texture_count=len(textures_array),
        group_count=saved_mod.group_count,
        bones_array_offset=bones_array_offset,
        group_data_array=saved_mod.group_data_array,
        bone_palette_count=saved_mod.bone_palette_count,
        sphere_x=saved_mod.sphere_x,
        sphere_y=saved_mod.sphere_y,
        sphere_z=saved_mod.sphere_z,
        sphere_w=saved_mod.sphere_w,
        box_min_x=saved_mod.box_min_x,
        box_min_y=saved_mod.box_min_y,
        box_min_z=saved_mod.box_min_z,
        box_min_w=saved_mod.box_min_w,
        box_max_x=saved_mod.box_max_x,
        box_max_y=saved_mod.box_max_y,
        box_max_z=saved_mod.box_max_z,
        box_max_w=saved_mod.box_max_w,
        unk_01=saved_mod.unk_01,
        unk_02=saved_mod.unk_02,
        unk_03=saved_mod.unk_03,
        unk_04=saved_mod.unk_04,
        unk_05=saved_mod.unk_05,
        unk_06=saved_mod.unk_06,
        unk_07=saved_mod.unk_07,
        unk_08=saved_mod.unk_08,
        unk_09=saved_mod.unk_09,
        unk_10=saved_mod.unk_10,
        unk_11=saved_mod.unk_11,
        unk_12=saved_mod.unk_12,
        bones_array=saved_mod.bones_array,
        bones_unk_matrix_array=saved_mod.bones_unk_matrix_array,
        bones_world_transform_matrix_array=saved_mod.
        bones_world_transform_matrix_array,
        unk_13=saved_mod.unk_13,
        bone_palette_array=saved_mod.bone_palette_array,
        textures_array=textures_array,
        materials_data_array=materials_array,
        meshes_array=meshes_array,
        meshes_array_2=meshes_array_2,
        vertex_buffer=vertex_buffer,
        vertex_buffer_2=saved_mod.vertex_buffer_2,
        index_buffer=index_buffer)
    mod.bones_array_offset = get_offset(mod,
                                        'bones_array') if mod.bone_count else 0
    mod.group_offset = get_offset(mod, 'group_data_array')
    mod.textures_array_offset = get_offset(mod, 'textures_array')
    mod.meshes_array_offset = get_offset(mod, 'meshes_array')
    mod.vertex_buffer_offset = get_offset(mod, 'vertex_buffer')
    mod.vertex_buffer_2_offset = get_offset(mod, 'vertex_buffer_2')
    mod.index_buffer_offset = get_offset(mod, 'index_buffer')
    return mod, get_textures_from_blender_objects(children_objects)
Пример #7
0
def export_mod156(parent_blender_object):
    '''The blender_object provided should have meshes as children'''
    try:
        saved_mod = Mod156(file_path=BytesIO(parent_blender_object.albam_imported_item.data))
    except AttributeError:
        raise ExportError("Can't export '{0}' to Mod156, the model to be exported "
                          "wasn't imported using Albam"
                          .format(parent_blender_object.name))

    children_objects = [child for child in parent_blender_object.children]
    empty_children = [c for c in children_objects if c.type == 'EMPTY']
    meshes_children = [c for c in children_objects if c.type == 'MESH']
    bounding_box = get_bounding_box_positions_from_blender_objects(children_objects)

    if len(meshes_children) < len(saved_mod.meshes_array) and empty_children:
        # There were failed meshes that were replaced as empties in the import
        # We need to remove the extra weight groups (or whaterver they are),
        # before exporting
        failed_indices = {i for i, obj in enumerate(parent_blender_object.children)
                          if obj.type == 'EMPTY'}
        new_bytes = []
        current_position = 0
        for i, mesh in enumerate(saved_mod.meshes_array):
            size = 144 * mesh.vertex_group_count
            data = saved_mod.meshes_array_2[current_position:current_position + size]
            current_position = current_position + size
            if i in failed_indices:
                continue
            else:
                new_bytes.extend(data)
        # the misterious extra 4 bytes for mod.156
        new_bytes.extend(saved_mod.meshes_array_2[-4:])
        meshes_array_2 = (ctypes.c_ubyte * len(new_bytes))(*new_bytes)
    elif len(meshes_children) != len(saved_mod.meshes_array) and not empty_children:
        raise ExportError("Can't import {0}, different meshes quantity ({1} vs {2}) "
                          "Support for this will come soon".format(parent_blender_object.name,
                                                                   len(saved_mod.meshes_array),
                                                                   len(children_objects)))
    else:
        meshes_array_2 = saved_mod.meshes_array_2

    textures_array, materials_array = _export_textures_and_materials(children_objects, saved_mod)
    meshes_array, vertex_buffer, index_buffer = _export_meshes(children_objects, bounding_box, saved_mod)

    bone_count = get_bone_count_from_blender_objects([parent_blender_object])
    if not bone_count:
        bones_array_offset = 0
    elif bone_count and saved_mod.unk_08:
        bones_array_offset = 176 + len(saved_mod.unk_12)
    else:
        bones_array_offset = 176

    mod = Mod156(id_magic=b'MOD',
                 version=156,
                 version_rev=1,
                 bone_count=bone_count,
                 mesh_count=get_mesh_count_from_blender_objects(children_objects),
                 material_count=len(materials_array),
                 vertex_count=get_vertex_count_from_blender_objects(children_objects),
                 face_count=(ctypes.sizeof(index_buffer) // 2) + 1,
                 edge_count=0,  # TODO: add edge_count
                 vertex_buffer_size=ctypes.sizeof(vertex_buffer),
                 vertex_buffer_2_size=len(saved_mod.vertex_buffer_2),
                 texture_count=len(textures_array),
                 group_count=saved_mod.group_count,
                 bones_array_offset=bones_array_offset,
                 group_data_array=saved_mod.group_data_array,
                 bone_palette_count=saved_mod.bone_palette_count,
                 sphere_x=saved_mod.sphere_x,
                 sphere_y=saved_mod.sphere_y,
                 sphere_z=saved_mod.sphere_z,
                 sphere_w=saved_mod.sphere_w,
                 box_min_x=saved_mod.box_min_x,
                 box_min_y=saved_mod.box_min_y,
                 box_min_z=saved_mod.box_min_z,
                 box_min_w=saved_mod.box_min_w,
                 box_max_x=saved_mod.box_max_x,
                 box_max_y=saved_mod.box_max_y,
                 box_max_z=saved_mod.box_max_z,
                 box_max_w=saved_mod.box_max_w,
                 unk_01=saved_mod.unk_01,
                 unk_02=saved_mod.unk_02,
                 unk_03=saved_mod.unk_03,
                 unk_04=saved_mod.unk_04,
                 unk_05=saved_mod.unk_05,
                 unk_06=saved_mod.unk_06,
                 unk_07=saved_mod.unk_07,
                 unk_08=saved_mod.unk_08,
                 unk_09=saved_mod.unk_09,
                 unk_10=saved_mod.unk_10,
                 unk_11=saved_mod.unk_11,
                 unk_12=saved_mod.unk_12,
                 bones_array=saved_mod.bones_array,
                 bones_unk_matrix_array=saved_mod.bones_unk_matrix_array,
                 bones_world_transform_matrix_array=saved_mod.bones_world_transform_matrix_array,
                 unk_13=saved_mod.unk_13,
                 bone_palette_array=saved_mod.bone_palette_array,
                 textures_array=textures_array,
                 materials_data_array=materials_array,
                 meshes_array=meshes_array,
                 meshes_array_2=meshes_array_2,
                 vertex_buffer=vertex_buffer,
                 vertex_buffer_2=saved_mod.vertex_buffer_2,
                 index_buffer=index_buffer
                 )
    mod.bones_array_offset = get_offset(mod, 'bones_array') if mod.bone_count else 0
    mod.group_offset = get_offset(mod, 'group_data_array')
    mod.textures_array_offset = get_offset(mod, 'textures_array')
    mod.meshes_array_offset = get_offset(mod, 'meshes_array')
    mod.vertex_buffer_offset = get_offset(mod, 'vertex_buffer')
    mod.vertex_buffer_2_offset = get_offset(mod, 'vertex_buffer_2')
    mod.index_buffer_offset = get_offset(mod, 'index_buffer')
    return mod, get_textures_from_blender_objects(children_objects)