BSPParser
Simple and modern library for parsing the Valve BSP format
Loading...
Searching...
No Matches
BSPParser

Simple and modern library for parsing the Valve BSP map format.

Documentation: https://taservers.github.io/BSPParser/

See also:

What's included

  • Class for parsing and abstracing the BSP file format for the Source engine.
  • Helper functions to simplify accessing the complex data structures of the BSP (see example below)
  • Enums and structs with decent coverage of the BSP lumps and their versions.
  • Runtime errors for issues when parsing the data due to corruption or a bug in the parser.

Example

Generating a triangle list for all models in the BSP:

#include "BSPParser.hpp"
// Load from a file on disk, an API, or somewhere in memory
const auto bspData = ...;
// Parse the data (you should wrap this in a try/catch)
const BspParser::Bsp bsp(bspData);
// We want to render the BSP, so pay the performance cost of smoothing displacement normals
bsp.smoothNeighbouringDisplacements();
// For each model...
bsp,
[&bsp](
const std::vector<BspParser::PhysModel>& physicsModels
) {
// For each face...
bsp,
model,
[&bsp](
const BspParser::Structs::TexInfo& textureInfo,
const std::span<const int32_t> surfaceEdges
) {
if (isFaceNoDraw(surfaceEdges, textureInfo)) {
return;
}
// For each vertex... (you can use getVertexCount to preallocate memory for a single face or the whole BSP)
bsp,
face,
plane,
textureInfo,
surfaceEdges,
[](const BspParser::Vertex& vertex) {
// Use vertex.position, vertex.normal, etc.
}
);
// For each index... (you can use getTriangleListIndexCount to preallocate memory here too)
bsp,
face,
surfaceEdges,
[](const int32_t index0, const int32_t index1, const int32_t index2) {
// Use triangle indices (always clockwise winding)
}
);
}
);
}
);
void generateTriangleListIndices(const Bsp &bsp, const Structs::Face &face, const std::span< const int32_t > surfaceEdges, const std::function< void(uint32_t i0, uint32_t i1, uint32_t i2)> &iteratee)
Definition: face-accessors.cpp:165
void iterateModels(const Bsp &bsp, const std::function< void(const Structs::Model &model, const std::vector< PhysModel > &physicsModels)> &iteratee)
Definition: face-accessors.cpp:16
void iterateFaces(const Bsp &bsp, const Structs::Model &model, const std::function< void(const Structs::Face &face, const Structs::Plane &plane, const Structs::TexInfo &textureInfo, std::span< const int32_t > surfaceEdges)> &iteratee)
Definition: face-accessors.cpp:34
void generateVertices(const Bsp &bsp, const Structs::Face &face, const Structs::Plane &plane, const Structs::TexInfo &textureInfo, const std::span< const int32_t > surfaceEdges, const std::function< void(const Vertex &vertex)> &iteratee)
Definition: face-accessors.cpp:133
Definition: bsp.hpp:29
Definition: geometry.hpp:21
Definition: models.hpp:7
Definition: geometry.hpp:8
Definition: textures.hpp:8
Definition: vertex.hpp:6

Generating colliders for all physmeshes in the BSP:

#include "BSPParser.hpp"
// Load from a file on disk, an API, or somewhere in memory
const auto bspData = ...;
// Parse the data (you should wrap this in a try/catch)
const BspParser::Bsp bsp(bspData);
// We don't want to render the BSP, so don't smooth normals this time
// bsp.smoothNeighbouringDisplacements();
// For each model...
bsp,
[&bsp](
const std::vector<BspParser::PhysModel>& physicsModels
) {
for (const auto& physicsModel : physicsModels) {
// You don't have to use PhyParser here, any solution for parsing .phy file data will do
const auto [solidsForModel, _] = PhyParser::parseSurfaces(physicsModel.collisionData, physicsModel.solidCount);
// Use solids to build your colliders...
}
}
);