1
0
Fork 0
mirror of https://codeberg.org/icewind/vbsp.git synced 2026-06-03 10:44:07 +02:00

wip obj converter

This commit is contained in:
Robin Appelman 2020-06-27 16:04:12 +02:00
commit 0bad24a370
6 changed files with 112 additions and 12 deletions

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
target target
Cargo.lock Cargo.lock
*.bench *.bench
*.obj

View file

@ -20,5 +20,9 @@ binread = "1.0"
parse-display = "0.1.2" parse-display = "0.1.2"
static_assertions = "1.1.0" static_assertions = "1.1.0"
[dev-dependencies]
obj = "0.10"
main_error = "0.1.0"
[features] [features]
bench = [] bench = []

65
examples/convert.rs Normal file
View file

@ -0,0 +1,65 @@
use main_error::MainError;
use obj::{Group, IndexTuple, Obj, ObjData, Object, SimplePolygon};
use vbsp::TextureFlags;
fn main() -> Result<(), MainError> {
let mut args = std::env::args();
let _ = args.next();
let data = std::fs::read(args.next().expect("No demo file provided"))?;
let bsp = vbsp::Bsp::read(&data)?;
let vertices = bsp
.vertices
.iter()
.map(|vertex| <[f32; 3]>::from(&vertex.position))
.collect();
let polygons = bsp
.original_faces()
.filter(|face| {
face.texture()
.map(|texture| {
!texture.flags.intersects(
TextureFlags::LIGHT
| TextureFlags::SKY2D
| TextureFlags::SKY
| TextureFlags::SKIP
| TextureFlags::NODRAW,
)
})
.unwrap_or_default()
})
.map(|face| {
SimplePolygon(
face.vertex_indexes()
.map(|vertex| IndexTuple(vertex as usize, None, None))
.collect(),
)
})
.collect();
let obj_data = ObjData {
position: vertices,
texture: Vec::new(),
normal: Vec::new(),
objects: vec![Object {
name: "".to_string(),
groups: vec![Group {
name: "".to_string(),
index: 0,
material: None,
polys: polygons,
}],
}],
material_libs: Vec::new(),
};
let obj = Obj {
data: obj_data,
path: Default::default(),
};
obj.save("out.obj")?;
Ok(())
}

View file

@ -1,8 +1,8 @@
fn main() -> Result<(), vbsp::BspError> { fn main() -> Result<(), vbsp::BspError> {
let mut args = std::env::args(); let mut args = std::env::args();
let _ = args.next(); let _ = args.next();
let data = std::fs::read(args.next().unwrap())?; let data = std::fs::read(args.next().expect("No demo file provided"))?;
let _ = vbsp::Bsp::read(&data)?; vbsp::Bsp::read(&data)?;
Ok(()) Ok(())
} }

View file

@ -229,6 +229,18 @@ impl Vector {
} }
} }
impl From<Vector> for [f32; 3] {
fn from(vector: Vector) -> Self {
[vector.x, vector.y, vector.z]
}
}
impl From<&Vector> for [f32; 3] {
fn from(vector: &Vector) -> Self {
[vector.x, vector.y, vector.z]
}
}
#[derive(Debug, Clone, BinRead)] #[derive(Debug, Clone, BinRead)]
pub struct TextureInfo { pub struct TextureInfo {
pub texture_scale: [f32; 4], pub texture_scale: [f32; 4],

View file

@ -3,6 +3,7 @@ mod data;
mod reader; mod reader;
use crate::bspfile::LumpType; use crate::bspfile::LumpType;
pub use crate::data::TextureFlags;
pub use crate::data::Vector; pub use crate::data::Vector;
use crate::data::*; use crate::data::*;
use binread::io::Cursor; use binread::io::Cursor;
@ -10,7 +11,7 @@ use binread::BinRead;
use bspfile::BspFile; use bspfile::BspFile;
use itertools::{GroupBy, Itertools}; use itertools::{GroupBy, Itertools};
use reader::LumpReader; use reader::LumpReader;
use std::{io::Read, iter::once, ops::Deref}; use std::{io::Read, ops::Deref};
use thiserror::Error; use thiserror::Error;
#[derive(Debug, Error)] #[derive(Debug, Error)]
@ -165,6 +166,7 @@ pub struct Bsp {
pub edges: Vec<Edge>, pub edges: Vec<Edge>,
pub surface_edges: Vec<SurfaceEdge>, pub surface_edges: Vec<SurfaceEdge>,
pub faces: Vec<Face>, pub faces: Vec<Face>,
pub original_faces: Vec<Face>,
pub vis_data: VisData, pub vis_data: VisData,
} }
@ -216,6 +218,9 @@ impl Bsp {
let faces = bsp_file let faces = bsp_file
.lump_reader(LumpType::Faces)? .lump_reader(LumpType::Faces)?
.read_vec(|r| r.read())?; .read_vec(|r| r.read())?;
let original_faces = bsp_file
.lump_reader(LumpType::OriginalFaces)?
.read_vec(|r| r.read())?;
let vis_data = bsp_file.lump_reader(LumpType::Visibility)?.read_visdata()?; let vis_data = bsp_file.lump_reader(LumpType::Visibility)?.read_visdata()?;
Ok({ Ok({
@ -236,6 +241,7 @@ impl Bsp {
edges, edges,
surface_edges, surface_edges,
faces, faces,
original_faces,
vis_data, vis_data,
} }
}) })
@ -299,6 +305,13 @@ impl Bsp {
} }
} }
} }
pub fn original_faces(&self) -> impl Iterator<Item = Handle<Face>> {
self.faces.iter().map(move |face| Handle {
bsp: self,
data: face,
})
}
} }
impl<'a, T> Handle<'a, T> { impl<'a, T> Handle<'a, T> {
@ -338,20 +351,25 @@ impl<'a> Handle<'a, Face> {
}) })
} }
pub fn vertices(&'a self) -> impl Iterator<Item = &'a Vertex> + 'a { pub fn vertices(&self) -> impl Iterator<Item = &'a Vertex> + 'a {
let bsp = self.bsp;
self.vertex_indexes()
.flat_map(move |vert_index| bsp.vertices.get(vert_index as usize))
}
pub fn vertex_indexes(&self) -> impl Iterator<Item = u16> + 'a {
let bsp = self.bsp;
(self.data.first_edge..(self.data.first_edge + self.data.num_edges as i32)) (self.data.first_edge..(self.data.first_edge + self.data.num_edges as i32))
.flat_map(move |surface_edge| self.bsp.surface_edges.get(surface_edge as usize)) .flat_map(move |surface_edge| bsp.surface_edges.get(surface_edge as usize))
.flat_map(move |surface_edge| { .flat_map(move |surface_edge| {
self.bsp bsp.edges
.edges
.get(surface_edge.edge_index()) .get(surface_edge.edge_index())
.map(|edge| (edge, surface_edge.direction())) .map(|edge| (edge, surface_edge.direction()))
}) })
.flat_map(|(edge, direction)| match direction { .map(|(edge, direction)| match direction {
EdgeDirection::FirstToLast => once(edge.start_index).chain(once(edge.end_index)), EdgeDirection::FirstToLast => edge.start_index,
EdgeDirection::LastToFirst => once(edge.end_index).chain(once(edge.start_index)), EdgeDirection::LastToFirst => edge.end_index,
}) })
.flat_map(move |vert_index| self.bsp.vertices.get(vert_index as usize))
} }
} }