mirror of
https://codeberg.org/icewind/vmdl.git
synced 2026-06-03 16:44:11 +02:00
bone names
This commit is contained in:
parent
b731b7aab1
commit
c58d911bf6
7 changed files with 63 additions and 28 deletions
|
|
@ -18,9 +18,7 @@ fn main() -> Result<(), vmdl::ModelError> {
|
||||||
let _vvd = Vvd::read(&data)?;
|
let _vvd = Vvd::read(&data)?;
|
||||||
|
|
||||||
for bone in mdl.bones {
|
for bone in mdl.bones {
|
||||||
dbg!(bone.flags);
|
println!("{}: from {} at {:?}", bone.name, bone.parent, bone.rot);
|
||||||
dbg!(bone.rot);
|
|
||||||
dbg!(bone.quaternion);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// let model = Model::from_parts(mdl, vtx, vvd);
|
// let model = Model::from_parts(mdl, vtx, vvd);
|
||||||
|
|
|
||||||
|
|
@ -252,8 +252,10 @@ fn model_to_model(model: &Model, loader: &Loader, skin: usize) -> CpuModel {
|
||||||
|
|
||||||
let transforms = model
|
let transforms = model
|
||||||
.bones()
|
.bones()
|
||||||
|
.filter(|bone| bone.name == "root")
|
||||||
|
.next()
|
||||||
.map(|bone| Mat4::from(cgmath::Quaternion::from(bone.rot)))
|
.map(|bone| Mat4::from(cgmath::Quaternion::from(bone.rot)))
|
||||||
.fold(Mat4::identity(), |a, b| a * b);
|
.unwrap_or_else(|| Matrix4::identity());
|
||||||
|
|
||||||
let geometries = model
|
let geometries = model
|
||||||
.meshes()
|
.meshes()
|
||||||
|
|
|
||||||
14
src/lib.rs
14
src/lib.rs
|
|
@ -203,20 +203,6 @@ impl<'a> Mesh<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_indexes<I: Iterator<Item = usize> + 'static, T: Readable>(
|
|
||||||
indexes: I,
|
|
||||||
data: &[u8],
|
|
||||||
) -> impl Iterator<Item = Result<T, ModelError>> + '_ {
|
|
||||||
indexes
|
|
||||||
.map(|index| {
|
|
||||||
data.get(index..).ok_or_else(|| ModelError::OutOfBounds {
|
|
||||||
data: type_name::<T>(),
|
|
||||||
offset: index,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.map(|data| data.and_then(|data| T::read(data)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn index_range(index: i32, count: i32, size: usize) -> impl Iterator<Item = usize> {
|
fn index_range(index: i32, count: i32, size: usize) -> impl Iterator<Item = usize> {
|
||||||
(0..count as usize)
|
(0..count as usize)
|
||||||
.map(move |i| i * size)
|
.map(move |i| i * size)
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,7 @@ pub use raw::*;
|
||||||
use std::mem::size_of;
|
use std::mem::size_of;
|
||||||
|
|
||||||
use crate::vvd::Vertex;
|
use crate::vvd::Vertex;
|
||||||
use crate::{
|
use crate::{read_relative, read_relative_iter, FixedString, ModelError, ReadRelative, Readable};
|
||||||
read_indexes, read_relative, read_relative_iter, FixedString, ModelError, ReadRelative,
|
|
||||||
Readable,
|
|
||||||
};
|
|
||||||
|
|
||||||
type Result<T> = std::result::Result<T, ModelError>;
|
type Result<T> = std::result::Result<T, ModelError>;
|
||||||
|
|
||||||
|
|
@ -44,7 +41,7 @@ impl Mdl {
|
||||||
|
|
||||||
let skin_table = read_relative::<u16, _>(data, header.skin_reference_indexes())?;
|
let skin_table = read_relative::<u16, _>(data, header.skin_reference_indexes())?;
|
||||||
|
|
||||||
let bones = read_indexes(header.bone_indexes(), data).collect::<Result<_>>()?;
|
let bones = read_relative(data, header.bone_indexes())?;
|
||||||
Ok(Mdl {
|
Ok(Mdl {
|
||||||
name,
|
name,
|
||||||
bones,
|
bones,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::mdl::raw::*;
|
use crate::mdl::raw::*;
|
||||||
use crate::mdl::Bone;
|
|
||||||
use crate::{index_range, Vector};
|
use crate::{index_range, Vector};
|
||||||
use std::mem::size_of;
|
use std::mem::size_of;
|
||||||
|
|
||||||
|
|
@ -211,7 +210,7 @@ impl StudioHeader {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bone_indexes(&self) -> impl Iterator<Item = usize> {
|
pub fn bone_indexes(&self) -> impl Iterator<Item = usize> {
|
||||||
index_range(self.bone_offset, self.bone_count, size_of::<Bone>())
|
index_range(self.bone_offset, self.bone_count, size_of::<BoneHeader>())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bone_controller_indexes(&self) -> impl Iterator<Item = usize> {
|
pub fn bone_controller_indexes(&self) -> impl Iterator<Item = usize> {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{index_range, FixedString};
|
use crate::{index_range, FixedString, ModelError, ReadRelative};
|
||||||
use crate::{Quaternion, RadianEuler, Vector};
|
use crate::{Quaternion, RadianEuler, Vector};
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use bytemuck::{Pod, Zeroable};
|
use bytemuck::{Pod, Zeroable};
|
||||||
|
|
@ -9,7 +9,7 @@ pub mod header2;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Zeroable, Pod)]
|
#[derive(Debug, Clone, Copy, Zeroable, Pod)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Bone {
|
pub struct BoneHeader {
|
||||||
pub sz_name_index: i32,
|
pub sz_name_index: i32,
|
||||||
pub parent: i32, // parent bone
|
pub parent: i32, // parent bone
|
||||||
pub bone_controller: [i32; 6], // bone controller index, -1 == none
|
pub bone_controller: [i32; 6], // bone controller index, -1 == none
|
||||||
|
|
@ -33,6 +33,60 @@ pub struct Bone {
|
||||||
reserved: [i32; 8], // remove as appropriate
|
reserved: [i32; 8], // remove as appropriate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static_assertions::const_assert_eq!(size_of::<BoneHeader>(), 216);
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct Bone {
|
||||||
|
pub name: String,
|
||||||
|
pub parent: i32, // parent bone
|
||||||
|
pub bone_controller: [i32; 6], // bone controller index, -1 == none
|
||||||
|
|
||||||
|
pub pos: Vector,
|
||||||
|
pub quaternion: Quaternion,
|
||||||
|
pub rot: RadianEuler,
|
||||||
|
pub pos_scale: Vector,
|
||||||
|
pub rot_scale: Vector,
|
||||||
|
|
||||||
|
pub pose_to_bone: [[f32; 3]; 4], // 3x4 matrix
|
||||||
|
pub q_alignment: Quaternion,
|
||||||
|
pub flags: BoneFlags,
|
||||||
|
pub proc_type: i32,
|
||||||
|
pub proc_index: i32, // procedural rule
|
||||||
|
pub physics_bone: i32, // index into physically simulated bone
|
||||||
|
pub surface_prop_idx: i32, // index into string table for property name
|
||||||
|
pub contents: i32, // See BSPFlags.h for the contents flags
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ReadRelative for Bone {
|
||||||
|
type Header = BoneHeader;
|
||||||
|
|
||||||
|
fn read(data: &[u8], header: Self::Header) -> Result<Self, ModelError> {
|
||||||
|
let name_bytes = data
|
||||||
|
.get(header.sz_name_index as usize..)
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
Ok(Bone {
|
||||||
|
name: String::read(name_bytes, ())?,
|
||||||
|
parent: header.parent,
|
||||||
|
bone_controller: header.bone_controller,
|
||||||
|
pos: header.pos,
|
||||||
|
quaternion: header.quaternion,
|
||||||
|
rot: header.rot,
|
||||||
|
pos_scale: header.pos_scale,
|
||||||
|
rot_scale: header.rot_scale,
|
||||||
|
pose_to_bone: header.pose_to_bone,
|
||||||
|
q_alignment: header.q_alignment,
|
||||||
|
flags: header.flags,
|
||||||
|
proc_type: header.proc_type,
|
||||||
|
proc_index: header.proc_index,
|
||||||
|
physics_bone: header.physics_bone,
|
||||||
|
surface_prop_idx: header.surface_prop_idx,
|
||||||
|
contents: header.contents,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Zeroable, Pod, Copy, Clone, Debug)]
|
#[derive(Zeroable, Pod, Copy, Clone, Debug)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct BoneFlags(u32);
|
pub struct BoneFlags(u32);
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ use crate::{ModelError, StringError};
|
||||||
use arrayvec::ArrayString;
|
use arrayvec::ArrayString;
|
||||||
use bytemuck::{Pod, Zeroable};
|
use bytemuck::{Pod, Zeroable};
|
||||||
use cgmath::{Deg, Euler, Rad, Rotation3, Vector3};
|
use cgmath::{Deg, Euler, Rad, Rotation3, Vector3};
|
||||||
use std::f32::consts::PI;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
use std::ops::{Add, Mul};
|
use std::ops::{Add, Mul};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue