mirror of
https://codeberg.org/icewind/vbsp-to-gltf.git
synced 2026-06-03 10:14:08 +02:00
move some code
This commit is contained in:
parent
c3f8ba242c
commit
23f9215481
5 changed files with 130 additions and 122 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
|
use crate::convert::map_coords;
|
||||||
|
use crate::error::Error;
|
||||||
use crate::gltf_builder::push_or_get_material;
|
use crate::gltf_builder::push_or_get_material;
|
||||||
use crate::{map_coords, Error};
|
|
||||||
use bytemuck::{offset_of, Pod, Zeroable};
|
use bytemuck::{offset_of, Pod, Zeroable};
|
||||||
use gltf_json::accessor::{ComponentType, GenericComponentType, Type};
|
use gltf_json::accessor::{ComponentType, GenericComponentType, Type};
|
||||||
use gltf_json::buffer::{Stride, Target, View};
|
use gltf_json::buffer::{Stride, Target, View};
|
||||||
|
|
|
||||||
123
src/convert.rs
Normal file
123
src/convert.rs
Normal file
|
|
@ -0,0 +1,123 @@
|
||||||
|
use gltf_json as json;
|
||||||
|
|
||||||
|
use crate::bsp::{bsp_models, push_bsp_model};
|
||||||
|
use crate::prop::push_or_get_model;
|
||||||
|
use crate::Error;
|
||||||
|
use cgmath::{Deg, Quaternion, Rotation3};
|
||||||
|
use gltf::Glb;
|
||||||
|
use gltf_json::scene::UnitQuaternion;
|
||||||
|
use gltf_json::validation::USize64;
|
||||||
|
use gltf_json::{Buffer, Index, Node, Root, Scene};
|
||||||
|
use std::borrow::Cow;
|
||||||
|
use tf_asset_loader::Loader;
|
||||||
|
use vbsp::Bsp;
|
||||||
|
|
||||||
|
pub fn export(bsp: Bsp, loader: &Loader) -> Result<Glb<'static>, Error> {
|
||||||
|
let mut buffer = Vec::new();
|
||||||
|
|
||||||
|
let mut root = Root::default();
|
||||||
|
|
||||||
|
for (model, offset) in bsp_models(&bsp)? {
|
||||||
|
let node = push_bsp_model(&mut buffer, &mut root, loader, &model, offset);
|
||||||
|
root.nodes.push(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
for prop in bsp.static_props() {
|
||||||
|
let mesh = push_or_get_model(&mut buffer, &mut root, loader, prop.model(), prop.skin);
|
||||||
|
let rotation = prop.rotation();
|
||||||
|
|
||||||
|
let node = Node {
|
||||||
|
camera: None,
|
||||||
|
children: None,
|
||||||
|
extensions: Default::default(),
|
||||||
|
extras: Default::default(),
|
||||||
|
matrix: None,
|
||||||
|
mesh: Some(mesh),
|
||||||
|
name: Some(prop.model().into()),
|
||||||
|
rotation: Some(UnitQuaternion([
|
||||||
|
rotation.v.x,
|
||||||
|
rotation.v.y,
|
||||||
|
rotation.v.z,
|
||||||
|
rotation.s,
|
||||||
|
])),
|
||||||
|
scale: None,
|
||||||
|
translation: Some(map_coords(prop.origin)),
|
||||||
|
skin: None,
|
||||||
|
weights: None,
|
||||||
|
};
|
||||||
|
root.nodes.push(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
let node_indices = 0..root.nodes.len();
|
||||||
|
let root_rotation = Quaternion::<f32>::from_angle_y(Deg(90.0));
|
||||||
|
let root_node = Node {
|
||||||
|
camera: None,
|
||||||
|
children: Some(node_indices.map(|index| Index::new(index as u32)).collect()),
|
||||||
|
extensions: Default::default(),
|
||||||
|
extras: Default::default(),
|
||||||
|
matrix: None,
|
||||||
|
mesh: None,
|
||||||
|
name: None,
|
||||||
|
rotation: Some(UnitQuaternion([
|
||||||
|
root_rotation.v.x,
|
||||||
|
root_rotation.v.y,
|
||||||
|
root_rotation.v.z,
|
||||||
|
root_rotation.s,
|
||||||
|
])),
|
||||||
|
scale: None,
|
||||||
|
translation: None,
|
||||||
|
skin: None,
|
||||||
|
weights: None,
|
||||||
|
};
|
||||||
|
let root_index = root.nodes.len();
|
||||||
|
root.nodes.push(root_node);
|
||||||
|
|
||||||
|
root.scenes = vec![Scene {
|
||||||
|
name: None,
|
||||||
|
extensions: None,
|
||||||
|
extras: Default::default(),
|
||||||
|
nodes: vec![Index::new(root_index as u32)],
|
||||||
|
}];
|
||||||
|
|
||||||
|
root.buffers.push(Buffer {
|
||||||
|
byte_length: USize64(buffer.len() as u64),
|
||||||
|
extensions: Default::default(),
|
||||||
|
extras: Default::default(),
|
||||||
|
name: None,
|
||||||
|
uri: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
let json_string = json::serialize::to_string(&root).expect("Serialization error");
|
||||||
|
let mut json_offset = json_string.len() as u32;
|
||||||
|
align_to_multiple_of_four(&mut json_offset);
|
||||||
|
|
||||||
|
pad_byte_vector(&mut buffer);
|
||||||
|
Ok(Glb {
|
||||||
|
header: gltf::binary::Header {
|
||||||
|
magic: *b"glTF",
|
||||||
|
version: 2,
|
||||||
|
length: json_offset + buffer.len() as u32,
|
||||||
|
},
|
||||||
|
bin: Some(Cow::Owned(buffer)),
|
||||||
|
json: Cow::Owned(json_string.into_bytes()),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn align_to_multiple_of_four(n: &mut u32) {
|
||||||
|
*n = (*n + 3) & !3;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pad_byte_vector(vec: &mut Vec<u8>) {
|
||||||
|
while vec.len() % 4 != 0 {
|
||||||
|
vec.push(0); // pad to multiple of four bytes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1 hammer unit is ~1.905cm
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub const UNIT_SCALE: f32 = 1.0 / (1.905 * 100.0);
|
||||||
|
|
||||||
|
pub fn map_coords<C: Into<[f32; 3]>>(vec: C) -> [f32; 3] {
|
||||||
|
let vec = vec.into();
|
||||||
|
[vec[1], vec[2], vec[0]]
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
|
use crate::convert::pad_byte_vector;
|
||||||
use crate::materials::{load_material_fallback, MaterialData, TextureData};
|
use crate::materials::{load_material_fallback, MaterialData, TextureData};
|
||||||
use crate::pad_byte_vector;
|
|
||||||
use gltf_json::buffer::View;
|
use gltf_json::buffer::View;
|
||||||
use gltf_json::extensions::texture::{
|
use gltf_json::extensions::texture::{
|
||||||
TextureTransform, TextureTransformOffset, TextureTransformRotation, TextureTransformScale,
|
TextureTransform, TextureTransformOffset, TextureTransformRotation, TextureTransformScale,
|
||||||
|
|
|
||||||
121
src/main.rs
121
src/main.rs
|
|
@ -1,21 +1,14 @@
|
||||||
use gltf_json as json;
|
|
||||||
mod bsp;
|
mod bsp;
|
||||||
|
pub mod convert;
|
||||||
mod error;
|
mod error;
|
||||||
pub mod gltf_builder;
|
pub mod gltf_builder;
|
||||||
mod materials;
|
mod materials;
|
||||||
mod prop;
|
mod prop;
|
||||||
|
|
||||||
use crate::bsp::{bsp_models, push_bsp_model};
|
use crate::convert::export;
|
||||||
use crate::prop::push_or_get_model;
|
|
||||||
use cgmath::{Deg, Quaternion, Rotation3};
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
pub use error::Error;
|
pub use error::Error;
|
||||||
use gltf::Glb;
|
|
||||||
use gltf_json::scene::UnitQuaternion;
|
|
||||||
use gltf_json::validation::USize64;
|
|
||||||
use gltf_json::{Buffer, Index, Node, Root, Scene};
|
|
||||||
use miette::Context;
|
use miette::Context;
|
||||||
use std::borrow::Cow;
|
|
||||||
use std::fs::{read, File};
|
use std::fs::{read, File};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use tf_asset_loader::Loader;
|
use tf_asset_loader::Loader;
|
||||||
|
|
@ -70,113 +63,3 @@ fn main() -> miette::Result<()> {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn export(bsp: Bsp, loader: &Loader) -> Result<Glb<'static>, Error> {
|
|
||||||
let mut buffer = Vec::new();
|
|
||||||
|
|
||||||
let mut root = Root::default();
|
|
||||||
|
|
||||||
for (model, offset) in bsp_models(&bsp)? {
|
|
||||||
let node = push_bsp_model(&mut buffer, &mut root, loader, &model, offset);
|
|
||||||
root.nodes.push(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
for prop in bsp.static_props() {
|
|
||||||
let mesh = push_or_get_model(&mut buffer, &mut root, loader, prop.model(), prop.skin);
|
|
||||||
let rotation = prop.rotation();
|
|
||||||
|
|
||||||
let node = Node {
|
|
||||||
camera: None,
|
|
||||||
children: None,
|
|
||||||
extensions: Default::default(),
|
|
||||||
extras: Default::default(),
|
|
||||||
matrix: None,
|
|
||||||
mesh: Some(mesh),
|
|
||||||
name: Some(prop.model().into()),
|
|
||||||
rotation: Some(UnitQuaternion([
|
|
||||||
rotation.v.x,
|
|
||||||
rotation.v.y,
|
|
||||||
rotation.v.z,
|
|
||||||
rotation.s,
|
|
||||||
])),
|
|
||||||
scale: None,
|
|
||||||
translation: Some(map_coords(prop.origin)),
|
|
||||||
skin: None,
|
|
||||||
weights: None,
|
|
||||||
};
|
|
||||||
root.nodes.push(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
let node_indices = 0..root.nodes.len();
|
|
||||||
let root_rotation = Quaternion::<f32>::from_angle_y(Deg(90.0));
|
|
||||||
let root_node = Node {
|
|
||||||
camera: None,
|
|
||||||
children: Some(node_indices.map(|index| Index::new(index as u32)).collect()),
|
|
||||||
extensions: Default::default(),
|
|
||||||
extras: Default::default(),
|
|
||||||
matrix: None,
|
|
||||||
mesh: None,
|
|
||||||
name: None,
|
|
||||||
rotation: Some(UnitQuaternion([
|
|
||||||
root_rotation.v.x,
|
|
||||||
root_rotation.v.y,
|
|
||||||
root_rotation.v.z,
|
|
||||||
root_rotation.s,
|
|
||||||
])),
|
|
||||||
scale: None,
|
|
||||||
translation: None,
|
|
||||||
skin: None,
|
|
||||||
weights: None,
|
|
||||||
};
|
|
||||||
let root_index = root.nodes.len();
|
|
||||||
root.nodes.push(root_node);
|
|
||||||
|
|
||||||
root.scenes = vec![Scene {
|
|
||||||
name: None,
|
|
||||||
extensions: None,
|
|
||||||
extras: Default::default(),
|
|
||||||
nodes: vec![Index::new(root_index as u32)],
|
|
||||||
}];
|
|
||||||
|
|
||||||
root.buffers.push(Buffer {
|
|
||||||
byte_length: USize64(buffer.len() as u64),
|
|
||||||
extensions: Default::default(),
|
|
||||||
extras: Default::default(),
|
|
||||||
name: None,
|
|
||||||
uri: None,
|
|
||||||
});
|
|
||||||
|
|
||||||
let json_string = json::serialize::to_string(&root).expect("Serialization error");
|
|
||||||
let mut json_offset = json_string.len() as u32;
|
|
||||||
align_to_multiple_of_four(&mut json_offset);
|
|
||||||
|
|
||||||
pad_byte_vector(&mut buffer);
|
|
||||||
Ok(Glb {
|
|
||||||
header: gltf::binary::Header {
|
|
||||||
magic: *b"glTF",
|
|
||||||
version: 2,
|
|
||||||
length: json_offset + buffer.len() as u32,
|
|
||||||
},
|
|
||||||
bin: Some(Cow::Owned(buffer)),
|
|
||||||
json: Cow::Owned(json_string.into_bytes()),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn align_to_multiple_of_four(n: &mut u32) {
|
|
||||||
*n = (*n + 3) & !3;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pad_byte_vector(vec: &mut Vec<u8>) {
|
|
||||||
while vec.len() % 4 != 0 {
|
|
||||||
vec.push(0); // pad to multiple of four bytes
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1 hammer unit is ~1.905cm
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub const UNIT_SCALE: f32 = 1.0 / (1.905 * 100.0);
|
|
||||||
|
|
||||||
pub fn map_coords<C: Into<[f32; 3]>>(vec: C) -> [f32; 3] {
|
|
||||||
let vec = vec.into();
|
|
||||||
[vec[1], vec[2], vec[0]]
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
|
use crate::convert::map_coords;
|
||||||
use crate::gltf_builder::push_or_get_material;
|
use crate::gltf_builder::push_or_get_material;
|
||||||
use crate::{map_coords, Error};
|
use crate::Error;
|
||||||
use bytemuck::{offset_of, Pod, Zeroable};
|
use bytemuck::{offset_of, Pod, Zeroable};
|
||||||
use gltf_json::accessor::{ComponentType, GenericComponentType, Type};
|
use gltf_json::accessor::{ComponentType, GenericComponentType, Type};
|
||||||
use gltf_json::buffer::{Stride, Target, View};
|
use gltf_json::buffer::{Stride, Target, View};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue