1
0
Fork 0
mirror of https://codeberg.org/icewind/vbsp.git synced 2026-06-03 18:54:05 +02:00

added most of the q3 bsp format

This commit is contained in:
Neil Danson 2016-12-20 22:37:05 +00:00
commit d322159d1b

View file

@ -1,100 +1,91 @@
extern crate byteorder; extern crate byteorder;
use byteorder::{LittleEndian, ReadBytesExt}; use byteorder::{LittleEndian, ReadBytesExt};
use std::fs::{File};
use std::io::*; use std::io::*;
use std::path::{Path};
#[derive(Debug)] #[derive(Debug)]
pub struct Header { pub struct Header {
pub i : char, pub i: char,
pub b : char, pub b: char,
pub s : char, pub s: char,
pub p : char pub p: char,
}
fn read_header(cursor: &mut Cursor<Vec<u8>>) -> Result<Header> {
let i = cursor.read_u8()? as char;
let b = cursor.read_u8()? as char;
let s = cursor.read_u8()? as char;
let p = cursor.read_u8()? as char;
Ok(Header {
i: i,
b: b,
s: s,
p: p,
})
}
fn read_version(cursor: &mut Cursor<Vec<u8>>) -> Result<i32> {
cursor.read_i32::<LittleEndian>()
} }
#[derive(Debug)] #[derive(Debug)]
pub struct DirEntry { pub struct DirEntry {
pub offset: i32, pub offset: i32,
pub length : i32 pub length: i32,
} }
#[derive(Debug)] fn read_directories(cursor: &mut Cursor<Vec<u8>>) -> Result<Vec<DirEntry>> {
pub struct Entity {
pub entities: String
}
#[derive(Debug)]
pub struct Texture {
pub name : String,
pub flags : i32,
pub contents : i32
}
#[derive(Debug)]
pub struct Plane {
pub normal: [f32; 3],
pub dist : f32
}
#[derive(Debug)]
pub struct BSP {
pub header : Header,
pub dir_entries : Vec<DirEntry>,
pub entities : Entity,
pub textures : Vec<Texture>,
pub planes : Vec<Plane>,
}
fn read_header(cursor : &mut Cursor<Vec<u8>>) -> Result<Header> {
let i = cursor.read_u8()? as char;
let b = cursor.read_u8()? as char;
let s = cursor.read_u8()? as char;
let p = cursor.read_u8()? as char;
Ok(Header {i : i, b : b, s : s, p : p})
}
fn read_version(cursor : &mut Cursor<Vec<u8>>) -> Result<i32> {
cursor.read_i32::<LittleEndian>()
}
fn read_directories(cursor : &mut Cursor<Vec<u8>>) -> Result<Vec<DirEntry>> {
let mut dir_entries = Vec::new(); let mut dir_entries = Vec::new();
for _ in 0 .. 16 { for _ in 0..16 {
let offset = cursor.read_i32::<LittleEndian>()?; let offset = cursor.read_i32::<LittleEndian>()?;
let length = cursor.read_i32::<LittleEndian>()?; let length = cursor.read_i32::<LittleEndian>()?;
dir_entries.push( DirEntry { offset : offset, length : length }); dir_entries.push(DirEntry {
offset: offset,
length: length,
});
} }
Ok(dir_entries) Ok(dir_entries)
} }
fn read_entities(cursor : &mut Cursor<Vec<u8>>, dir_entry : &DirEntry) -> Result<Entity> { #[derive(Debug)]
pub struct Entity {
pub entities: String,
}
fn read_entities(cursor: &mut Cursor<Vec<u8>>, dir_entry: &DirEntry) -> Result<Entity> {
let mut entities = Vec::with_capacity(dir_entry.length as usize); let mut entities = Vec::with_capacity(dir_entry.length as usize);
cursor.set_position(dir_entry.offset as u64); cursor.set_position(dir_entry.offset as u64);
for _ in 0 .. dir_entry.length { for _ in 0..dir_entry.length {
let data = cursor.read_u8()?; let data = cursor.read_u8()?;
entities.push(data); entities.push(data);
} }
let entities = String::from_utf8(entities).unwrap(); let entities = String::from_utf8(entities).unwrap();
Ok(Entity { entities: entities })
Ok (Entity { entities : entities})
} }
fn read_entry<F, T>(cursor : &mut Cursor<Vec<u8>>, dir_entry : &DirEntry, mut f : F ) -> Result<Vec<T>> where F : FnMut(&mut Cursor<Vec<u8>>) -> Result<T> { fn read_entry<F, T>(cursor: &mut Cursor<Vec<u8>>, dir_entry: &DirEntry, mut f: F) -> Result<Vec<T>>
where F: FnMut(&mut Cursor<Vec<u8>>) -> Result<T>
{
let mut entries = Vec::new(); let mut entries = Vec::new();
cursor.set_position(dir_entry.offset as u64); cursor.set_position(dir_entry.offset as u64);
let end_pos = (dir_entry.offset + dir_entry.length) as u64; let end_pos = (dir_entry.offset + dir_entry.length) as u64;
while cursor.position() < end_pos { while cursor.position() < end_pos {
let entry = f(cursor)?; let entry = f(cursor)?;
entries.push(entry); entries.push(entry);
} }
Ok (entries) Ok(entries)
} }
fn read_texture(cursor : &mut Cursor<Vec<u8>>) -> Result<Texture> { #[derive(Debug)]
pub struct Texture {
pub name: String,
pub flags: i32,
pub contents: i32,
}
fn read_texture(cursor: &mut Cursor<Vec<u8>>) -> Result<Texture> {
let mut texture = Vec::new(); let mut texture = Vec::new();
for _ in 0 .. 64 { for _ in 0..64 {
let data = cursor.read_u8()?; let data = cursor.read_u8()?;
if data != 0u8 { if data != 0u8 {
texture.push(data); texture.push(data);
@ -103,34 +94,276 @@ fn read_texture(cursor : &mut Cursor<Vec<u8>>) -> Result<Texture> {
let texture_name = String::from_utf8(texture).unwrap(); let texture_name = String::from_utf8(texture).unwrap();
let flags = cursor.read_i32::<LittleEndian>()?; let flags = cursor.read_i32::<LittleEndian>()?;
let contents = cursor.read_i32::<LittleEndian>()?; let contents = cursor.read_i32::<LittleEndian>()?;
Ok (Texture { name : texture_name, flags : flags, contents : contents }) Ok(Texture {
name: texture_name,
flags: flags,
contents: contents,
})
} }
fn read_plane(cursor : &mut Cursor<Vec<u8>>) -> Result<Plane> { #[derive(Debug)]
pub struct Plane {
pub normal: [f32; 3],
pub dist: f32,
}
fn read_plane(cursor: &mut Cursor<Vec<u8>>) -> Result<Plane> {
let x = cursor.read_f32::<LittleEndian>()?; let x = cursor.read_f32::<LittleEndian>()?;
let y = cursor.read_f32::<LittleEndian>()?; let y = cursor.read_f32::<LittleEndian>()?;
let z = cursor.read_f32::<LittleEndian>()?; let z = cursor.read_f32::<LittleEndian>()?;
let dist = cursor.read_f32::<LittleEndian>()?; let dist = cursor.read_f32::<LittleEndian>()?;
let plane = Plane { normal : [x,y,z], dist : dist }; let plane = Plane {
Ok (plane) normal: [x, y, z],
dist: dist,
};
Ok(plane)
} }
pub fn read_bsp(filename : &str) -> Result<BSP> { #[derive(Debug)]
let path = Path::new(filename); pub struct Node {
let mut file = File::open(path).unwrap(); pub plane: i32,
let mut bytes = Vec::new(); pub children: [i32; 2],
file.read_to_end(&mut bytes).unwrap(); pub mins: [i32; 3],
pub maxs: [i32; 3],
}
fn read_node(cursor: &mut Cursor<Vec<u8>>) -> Result<Node> {
let plane = cursor.read_i32::<LittleEndian>()?;
let children = [cursor.read_i32::<LittleEndian>()?, cursor.read_i32::<LittleEndian>()?];
let mins = [cursor.read_i32::<LittleEndian>()?,
cursor.read_i32::<LittleEndian>()?,
cursor.read_i32::<LittleEndian>()?];
let maxs = [cursor.read_i32::<LittleEndian>()?,
cursor.read_i32::<LittleEndian>()?,
cursor.read_i32::<LittleEndian>()?];
let node = Node {
plane: plane,
children: children,
mins: mins,
maxs: maxs,
};
Ok(node)
}
#[derive(Debug)]
pub struct Leaf {
pub cluster: i32,
pub area: i32,
pub mins: [i32; 3],
pub maxs: [i32; 3],
pub leaf_face: i32,
pub num_leaf_faces: i32,
pub leaf_brush: i32,
pub num_leaf_brushes: i32,
}
fn read_leaf(cursor: &mut Cursor<Vec<u8>>) -> Result<Leaf> {
let cluster = cursor.read_i32::<LittleEndian>()?;
let area = cursor.read_i32::<LittleEndian>()?;
let mins = [cursor.read_i32::<LittleEndian>()?,
cursor.read_i32::<LittleEndian>()?,
cursor.read_i32::<LittleEndian>()?];
let maxs = [cursor.read_i32::<LittleEndian>()?,
cursor.read_i32::<LittleEndian>()?,
cursor.read_i32::<LittleEndian>()?];
let leaf_face = cursor.read_i32::<LittleEndian>()?;
let num_leaf_faces = cursor.read_i32::<LittleEndian>()?;
let leaf_brush = cursor.read_i32::<LittleEndian>()?;
let num_leaf_brushes = cursor.read_i32::<LittleEndian>()?;
let leaf = Leaf {
cluster: cluster,
area: area,
mins: mins,
maxs: maxs,
leaf_face: leaf_face,
num_leaf_faces: num_leaf_faces,
leaf_brush: leaf_brush,
num_leaf_brushes: num_leaf_brushes,
};
Ok(leaf)
}
#[derive(Debug)]
pub struct LeafFace {
pub face: i32,
}
fn read_leaf_face(cursor: &mut Cursor<Vec<u8>>) -> Result<LeafFace> {
let face = cursor.read_i32::<LittleEndian>()?;
let leaf_face = LeafFace { face: face };
Ok(leaf_face)
}
#[derive(Debug)]
pub struct LeafBrush {
pub brush: i32,
}
fn read_leaf_brush(cursor: &mut Cursor<Vec<u8>>) -> Result<LeafBrush> {
let brush = cursor.read_i32::<LittleEndian>()?;
let leaf_brush = LeafBrush { brush: brush };
Ok(leaf_brush)
}
#[derive(Debug)]
pub struct Model {
pub mins: [f32; 3],
pub maxs: [f32; 3],
pub face: i32,
pub num_faces: i32,
pub brush: i32,
pub num_brushes: i32,
}
fn read_model(cursor: &mut Cursor<Vec<u8>>) -> Result<Model> {
let mins = [cursor.read_f32::<LittleEndian>()?,
cursor.read_f32::<LittleEndian>()?,
cursor.read_f32::<LittleEndian>()?];
let maxs = [cursor.read_f32::<LittleEndian>()?,
cursor.read_f32::<LittleEndian>()?,
cursor.read_f32::<LittleEndian>()?];
let face = cursor.read_i32::<LittleEndian>()?;
let num_faces = cursor.read_i32::<LittleEndian>()?;
let brush = cursor.read_i32::<LittleEndian>()?;
let num_brushes = cursor.read_i32::<LittleEndian>()?;
let model = Model {
mins: mins,
maxs: maxs,
face: face,
num_faces: num_faces,
brush: brush,
num_brushes: num_brushes,
};
Ok(model)
}
#[derive(Debug)]
pub struct Brush {
pub brush_side: i32,
pub num_brush_sides: i32,
pub texture: i32,
}
fn read_brush(cursor: &mut Cursor<Vec<u8>>) -> Result<Brush> {
let brush_side = cursor.read_i32::<LittleEndian>()?;
let num_brush_sides = cursor.read_i32::<LittleEndian>()?;
let texture = cursor.read_i32::<LittleEndian>()?;
let brush = Brush {
brush_side: brush_side,
num_brush_sides: num_brush_sides,
texture: texture,
};
Ok(brush)
}
#[derive(Debug)]
pub struct BrushSide {
pub plane: i32,
pub texture: i32,
}
fn read_brush_side(cursor: &mut Cursor<Vec<u8>>) -> Result<BrushSide> {
let plane = cursor.read_i32::<LittleEndian>()?;
let texture = cursor.read_i32::<LittleEndian>()?;
let brush_side = BrushSide {
plane: plane,
texture: texture,
};
Ok(brush_side)
}
#[derive(Debug)]
pub struct Vertex {
pub position: [f32; 3],
pub tex_coord1: [f32; 2],
pub tex_coord2: [f32; 2],
pub normal: [f32; 3],
pub color: [u8; 4],
}
fn read_vertex(cursor: &mut Cursor<Vec<u8>>) -> Result<Vertex> {
let position = [cursor.read_f32::<LittleEndian>()?,
cursor.read_f32::<LittleEndian>()?,
cursor.read_f32::<LittleEndian>()?];
let tex_coord1 = [cursor.read_f32::<LittleEndian>()?, cursor.read_f32::<LittleEndian>()?];
let tex_coord2 = [cursor.read_f32::<LittleEndian>()?, cursor.read_f32::<LittleEndian>()?];
let normal = [cursor.read_f32::<LittleEndian>()?,
cursor.read_f32::<LittleEndian>()?,
cursor.read_f32::<LittleEndian>()?];
let color = [cursor.read_u8()?, cursor.read_u8()?, cursor.read_u8()?, cursor.read_u8()?];
let vertex = Vertex {
position: position,
tex_coord1: tex_coord1,
tex_coord2: tex_coord2,
normal: normal,
color: color,
};
Ok(vertex)
}
#[derive(Debug)]
pub struct MeshVert {
pub offset: i32,
}
fn read_mesh_vert(cursor: &mut Cursor<Vec<u8>>) -> Result<MeshVert> {
let offset = cursor.read_i32::<LittleEndian>()?;
let mesh_vert = MeshVert { offset: offset };
Ok(mesh_vert)
}
#[derive(Debug)]
pub struct BSP {
pub header: Header,
pub dir_entries: Vec<DirEntry>,
pub entities: Entity,
pub textures: Vec<Texture>,
pub planes: Vec<Plane>,
pub nodes: Vec<Node>,
pub leafs: Vec<Leaf>,
pub leaf_faces: Vec<LeafFace>,
pub leaf_brushes: Vec<LeafBrush>,
pub models: Vec<Model>,
pub brushes: Vec<Brush>,
pub brush_sides: Vec<BrushSide>,
pub vertexes: Vec<Vertex>,
pub mesh_verts: Vec<MeshVert>,
}
pub fn read_bsp(bytes: Vec<u8>) -> Result<BSP> {
let mut cursor = Cursor::new(bytes); let mut cursor = Cursor::new(bytes);
let header = read_header(&mut cursor)?; let header = read_header(&mut cursor)?;
let version = read_version(&mut cursor)?; let version = read_version(&mut cursor)?;
assert_eq!(version, 0x2e); assert_eq!(version, 0x2e);
let dir_entries = read_directories(&mut cursor)?; let dir_entries = read_directories(&mut cursor)?;
let entities = read_entities(&mut cursor, &dir_entries[0])?; let entities = read_entities(&mut cursor, &dir_entries[0])?;
let textures = read_entry(&mut cursor, &dir_entries[1], read_texture)?; //read_textures(&mut cursor, &dir_entries[1])?; let textures = read_entry(&mut cursor, &dir_entries[1], read_texture)?;
let planes = read_entry(&mut cursor, &dir_entries[2], read_plane)?; let planes = read_entry(&mut cursor, &dir_entries[2], read_plane)?;
Ok ({ BSP { header : header, let nodes = read_entry(&mut cursor, &dir_entries[3], read_node)?;
dir_entries : dir_entries, let leafs = read_entry(&mut cursor, &dir_entries[4], read_leaf)?;
entities : entities, let leaf_faces = read_entry(&mut cursor, &dir_entries[5], read_leaf_face)?;
textures : textures, let leaf_brushes = read_entry(&mut cursor, &dir_entries[6], read_leaf_brush)?;
planes : planes }}) let models = read_entry(&mut cursor, &dir_entries[7], read_model)?;
let brushes = read_entry(&mut cursor, &dir_entries[8], read_brush)?;
let brush_sides = read_entry(&mut cursor, &dir_entries[9], read_brush_side)?;
let vertexes = read_entry(&mut cursor, &dir_entries[10], read_vertex)?;
let mesh_verts = read_entry(&mut cursor, &dir_entries[11], read_mesh_vert)?;
Ok({
BSP {
header: header,
dir_entries: dir_entries,
entities: entities,
textures: textures,
planes: planes,
nodes: nodes,
leafs: leafs,
leaf_faces: leaf_faces,
leaf_brushes: leaf_brushes,
models: models,
brushes: brushes,
brush_sides: brush_sides,
vertexes: vertexes,
mesh_verts: mesh_verts,
}
})
} }