📖 Documentation: https://secondmouseau.github.io/SwiftX/
A small, native-Swift reader for DirectX .x model geometry — the legacy Microsoft retained-mode
mesh format, still used by tools and simulators such as RailSim.
.x ships in four flavours, distinguished by the xof header: txt (text), bin (binary
tokens), tzip (MSZip-compressed text), and bzip (MSZip-compressed binary). SwiftX reads
all four (32- and 64-bit floats), extracting geometry only — vertices and triangle faces (polygons
are fan-triangulated) across every Mesh in the file — and skipping templates, frames, normals,
materials and textures.
- Pure Swift, no third-party dependencies.
- Validated against a 116-file RailSim corpus: geometry bbox-exact vs Assimp on every file.
dependencies: [
.package(url: "https://github.com/SecondMouseAU/SwiftX.git", from: "1.0.0"),
],
// target:
.target(name: "YourTarget", dependencies: [.product(name: "SwiftX", package: "SwiftX")]),import SwiftX
let mesh = try X.read(contentsOf: url) // welded, degenerate faces dropped
print(mesh.vertexCount, mesh.triangleCount)
for t in 0..<mesh.triangleCount {
let i = t * 3
let a = mesh.positions[Int(mesh.indices[i])]
// …
}Everything is configurable via X.Options — weldEpsilon (seam welding; nil to keep raw indexing),
dropDegenerate, scale, and flipZ (left-/right-handed). X.looksLikeX(data) sniffs the "xof "
signature.
SwiftX is a geometry reader: no rig/animation, materials, textures, or writing. The compressed
flavours (tzip/bzip) use Apple's Compression framework for raw-DEFLATE; on platforms without it,
compressed files throw X.Error.compressionUnavailable while text/binary .x still work. Multi-block
MSZip (files >32 KB uncompressed) is a future addition — single-block (the vast majority of parts) is
fully supported.
In simulators like RailSim, the
.xfiles are individual parts and the assembly (which parts, how many, where placed) lives in separate text definition files. SwiftX reads the parts; the assembly is a separate concern.
MIT.