Skip to content

.bsp spelunker's guide: testing a theory

Jared Ketterer edited this page Mar 23, 2022 · 3 revisions

Short experiment

The following experiment was used to confirm estimates about some values in respawn.titanfall.Mesh
Specifically if first_vertex & num_vertices pointed to the same vertex data found by the vertices_of_model method
Once confirmed, this was used to find a fast vertex buffer building approach for glview

theory.py

import fnmatch
import os

import bsp_tool

# lay your tools out in an orderly fashion on the operating table...
quake = bsp_tool.branches.id_software.quake
r1 = bsp_tool.branches.respawn.titanfall
r2 = bsp_tool.branches.respawn.titanfall2
r5 = bsp_tool.branches.respawn.apex_legends
source = bsp_tool.branches.valve.source

# collect maps to experiment on
map_dir = "E:/Mod/Titanfall/maps"
print("Loading .bsp files...")
maps = []
for filename in fnmatch.filter(os.listdir(map_dir), "*.bsp"):
    print(filename)
    maps.append(bsp_tool.load_bsp(os.path.join(map_dir, filename)))
print("All .bsp files loaded!\n")

# EXPERIMENT:
for bsp in maps:
    print(f"Parsing {bsp.filename}...", end="")
    with open(f"{bsp.filename}.log", "w") as log:
        for i, mesh in enumerate(bsp.MESHES):
            material_sort = bsp.MATERIAL_SORT[mesh.material_sort]
            vertex_range = [mesh.first_vertex + j for j in range(mesh.num_vertices + 1)]
            mi_start = mesh.first_mesh_index
            mi_end = mesh.first_mesh_index + mesh.num_triangles * 3
            if set(vertex_range) != {*bsp.MESH_INDICES[mi_start:mi_end]}:
                vertex_range_str = f"({mesh.first_vertex}..{mesh.first_vertex + mesh.num_vertices + 1})"
                lump_str = f"{r1.Flags(mesh.flags & r1.Flags.MASK_VERTEX).name}"
                log.write(f"MESH {i} ({lump_str}): {vertex_range_str} != {set(bsp.MESH_INDICES[mi_start:mi_end])}\n")
                # e.g. "MESH 0 (VERTEX_BUMP_LIT): (0..15) != {???}"
    print("Done!")

print("Experiment complete!")

results

The experiment generated an empty log for each of Titanfall 1's .bsp files (once mesh.num_vertices was ammended to mesh.num_vertices + 1)
Definitely a success, and it provides some visual feedback as well being as a performance helper for visualising
Really helps with understanding of how this part of the format can be used too.