mirror of
https://codeberg.org/icewind/vmdl.git
synced 2026-06-03 16:44:11 +02:00
basic vvd
This commit is contained in:
parent
b0d3245e07
commit
fc98416aa3
5 changed files with 137 additions and 17 deletions
|
|
@ -185,7 +185,7 @@ impl StripHeader {
|
||||||
index_range(
|
index_range(
|
||||||
self.bone_state_change_offset,
|
self.bone_state_change_offset,
|
||||||
self.bone_state_change_count,
|
self.bone_state_change_count,
|
||||||
todo!(),
|
1,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
16
src/vvd.rs
16
src/vvd.rs
|
|
@ -1,16 +0,0 @@
|
||||||
use binrw::BinRead;
|
|
||||||
|
|
||||||
pub const MDL_VERSION: i32 = 7;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, BinRead)]
|
|
||||||
pub struct Header {
|
|
||||||
pub id: i32,
|
|
||||||
pub version: i32,
|
|
||||||
pub checksum: [u8; 4],
|
|
||||||
pub lod_count: i32,
|
|
||||||
pub lod_vertex_count: [i32; 8],
|
|
||||||
pub fixup_count: i32,
|
|
||||||
pub fixup_index: i32,
|
|
||||||
pub vertex_index: i32,
|
|
||||||
pub tangent_index: i32,
|
|
||||||
}
|
|
||||||
37
src/vvd/mod.rs
Normal file
37
src/vvd/mod.rs
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
mod raw;
|
||||||
|
|
||||||
|
use crate::vvd::raw::VvdHeader;
|
||||||
|
use crate::ModelError;
|
||||||
|
use binrw::BinReaderExt;
|
||||||
|
pub use raw::{BoneWeight, Tangent, Vertex};
|
||||||
|
use std::io::Cursor;
|
||||||
|
|
||||||
|
type Result<T> = std::result::Result<T, ModelError>;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Vvd {
|
||||||
|
pub header: VvdHeader,
|
||||||
|
pub vertices: Vec<Vertex>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Vvd {
|
||||||
|
pub fn read(data: &[u8]) -> Result<Self> {
|
||||||
|
let mut reader = Cursor::new(data);
|
||||||
|
let header: VvdHeader = reader.read_le()?;
|
||||||
|
Ok(Vvd {
|
||||||
|
vertices: header
|
||||||
|
.vertex_indexes(0)
|
||||||
|
.unwrap()
|
||||||
|
.map(|index| {
|
||||||
|
let data = data.get(index..).ok_or_else(|| ModelError::OutOfBounds {
|
||||||
|
data: "Vertex",
|
||||||
|
offset: index,
|
||||||
|
})?;
|
||||||
|
let mut reader = Cursor::new(data);
|
||||||
|
Ok(reader.read_le()?)
|
||||||
|
})
|
||||||
|
.collect::<Result<_>>()?,
|
||||||
|
header,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
92
src/vvd/raw.rs
Normal file
92
src/vvd/raw.rs
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
use crate::{index_range, Vector};
|
||||||
|
use binrw::BinRead;
|
||||||
|
use std::mem::size_of;
|
||||||
|
|
||||||
|
pub const MDL_VERSION: i32 = 7;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, BinRead)]
|
||||||
|
pub struct VvdHeader {
|
||||||
|
pub id: i32,
|
||||||
|
pub version: i32,
|
||||||
|
pub checksum: [u8; 4],
|
||||||
|
pub lod_count: i32,
|
||||||
|
lod_vertex_count: [i32; 8],
|
||||||
|
fixup_count: i32,
|
||||||
|
fixup_index: i32,
|
||||||
|
vertex_index: i32,
|
||||||
|
tangent_index: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VvdHeader {
|
||||||
|
pub fn fixup_indexes(&self) -> impl Iterator<Item = usize> {
|
||||||
|
index_range(
|
||||||
|
self.fixup_index,
|
||||||
|
self.fixup_count,
|
||||||
|
size_of::<VertexFileFixup>(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn vertex_indexes(&self, lod: i32) -> Option<impl Iterator<Item = usize>> {
|
||||||
|
if lod > 0 && lod > self.fixup_count {
|
||||||
|
todo!("lod fixup not supported")
|
||||||
|
}
|
||||||
|
if lod < self.lod_count {
|
||||||
|
Some(index_range(
|
||||||
|
self.vertex_index,
|
||||||
|
self.lod_vertex_count[lod as usize],
|
||||||
|
size_of::<Vertex>(),
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tangent_indexes(&self, lod: i32) -> Option<impl Iterator<Item = usize>> {
|
||||||
|
if lod > 0 && lod > self.fixup_count {
|
||||||
|
todo!("lod fixup not supported")
|
||||||
|
}
|
||||||
|
if lod < self.lod_count {
|
||||||
|
Some(index_range(
|
||||||
|
self.tangent_index,
|
||||||
|
self.lod_vertex_count[lod as usize],
|
||||||
|
size_of::<Vertex>(),
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, BinRead)]
|
||||||
|
pub struct VertexFileFixup {
|
||||||
|
pub lod: i32,
|
||||||
|
pub source_vertex_id: i32,
|
||||||
|
pub vertex_count: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, BinRead)]
|
||||||
|
pub struct Vertex {
|
||||||
|
pub bone_weights: BoneWeight,
|
||||||
|
pub position: Vector,
|
||||||
|
pub normal: Vector,
|
||||||
|
pub texture_coordinates: [f32; 2],
|
||||||
|
}
|
||||||
|
|
||||||
|
static_assertions::const_assert_eq!(size_of::<Vertex>(), 48);
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, BinRead)]
|
||||||
|
pub struct BoneWeight {
|
||||||
|
pub weight: [f32; 3],
|
||||||
|
pub bone: [u8; 3],
|
||||||
|
pub bone_count: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
static_assertions::const_assert_eq!(size_of::<BoneWeight>(), 16);
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, BinRead)]
|
||||||
|
pub struct Tangent {
|
||||||
|
pub x: f32,
|
||||||
|
pub y: f32,
|
||||||
|
pub z: f32,
|
||||||
|
pub w: f32,
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use std::fs::read;
|
use std::fs::read;
|
||||||
use vmdl::mdl::Mdl;
|
use vmdl::mdl::Mdl;
|
||||||
use vmdl::vtx::Vtx;
|
use vmdl::vtx::Vtx;
|
||||||
|
use vmdl::vvd::Vvd;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_mdl() {
|
fn parse_mdl() {
|
||||||
|
|
@ -13,3 +14,9 @@ fn parse_vtx() {
|
||||||
let data = read("data/barrel01.dx90.vtx").unwrap();
|
let data = read("data/barrel01.dx90.vtx").unwrap();
|
||||||
Vtx::read(&data).unwrap();
|
Vtx::read(&data).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_vvd() {
|
||||||
|
let data = read("data/barrel01.vvd").unwrap();
|
||||||
|
Vvd::read(&data).unwrap();
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue