mirror of
https://codeberg.org/icewind/vbsp.git
synced 2026-06-03 18:54:05 +02:00
wip obj converter
This commit is contained in:
parent
9b18522190
commit
0bad24a370
6 changed files with 112 additions and 12 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,3 +1,4 @@
|
||||||
target
|
target
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
*.bench
|
*.bench
|
||||||
|
*.obj
|
||||||
|
|
@ -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
65
examples/convert.rs
Normal 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(())
|
||||||
|
}
|
||||||
|
|
@ -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(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
12
src/data.rs
12
src/data.rs
|
|
@ -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],
|
||||||
|
|
|
||||||
36
src/lib.rs
36
src/lib.rs
|
|
@ -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))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue