mirror of
https://codeberg.org/icewind/vmdl.git
synced 2026-06-03 08:34:23 +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(
|
||||
self.bone_state_change_offset,
|
||||
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 vmdl::mdl::Mdl;
|
||||
use vmdl::vtx::Vtx;
|
||||
use vmdl::vvd::Vvd;
|
||||
|
||||
#[test]
|
||||
fn parse_mdl() {
|
||||
|
|
@ -13,3 +14,9 @@ fn parse_vtx() {
|
|||
let data = read("data/barrel01.dx90.vtx").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