mirror of
https://codeberg.org/icewind/vmdl.git
synced 2026-06-03 08:34:23 +02:00
wips
This commit is contained in:
parent
a264e1c939
commit
50144ca1dd
8 changed files with 45 additions and 18 deletions
|
|
@ -19,16 +19,12 @@ fn main() -> Result<(), vmdl::ModelError> {
|
|||
let _vvd = Vvd::read(&data)?;
|
||||
|
||||
println!("{:?}", mdl.header.flags);
|
||||
dbg!(mdl.local_animations);
|
||||
// for bone in mdl.bones {
|
||||
// println!(
|
||||
// "{}: from {} at\n\t{:?}\n\t{:?}",
|
||||
// bone.name,
|
||||
// bone.parent,
|
||||
// bone.quaternion,
|
||||
// bone.pose_to_bone.rotation()
|
||||
// );
|
||||
// }
|
||||
for bone in mdl.bones {
|
||||
println!(
|
||||
"{}: from {} at\n\t{:?}\n\t{:?}",
|
||||
bone.name, bone.parent, bone.quaternion, bone.q_alignment
|
||||
);
|
||||
}
|
||||
|
||||
// let model = Model::from_parts(mdl, vtx, vvd);
|
||||
// for strip in model.vertex_strips() {
|
||||
|
|
|
|||
|
|
@ -262,7 +262,8 @@ fn model_to_model(model: &Model, loader: &Loader, skin: usize) -> CpuModel {
|
|||
|
||||
let positions: Vec<Vec3> = mesh
|
||||
.vertices()
|
||||
.map(|vertex| map_coords(vertex.position + offset) * 10.0)
|
||||
.map(|vertex| model.vertex_to_world_space(vertex))
|
||||
.map(|position| map_coords(position) * 10.0)
|
||||
.map(|vertex: Vec3| (transforms * vertex.extend(1.0)).truncate())
|
||||
.collect();
|
||||
let normals: Vec<Vec3> = mesh.vertices().map(|vertex| vertex.normal.into()).collect();
|
||||
|
|
|
|||
10
src/lib.rs
10
src/lib.rs
|
|
@ -148,6 +148,16 @@ impl Model {
|
|||
pub fn poses(&self) -> impl Iterator<Item = &PoseParameterDescription> {
|
||||
self.mdl.pose_parameters.iter()
|
||||
}
|
||||
|
||||
pub fn vertex_to_world_space(&self, vertex: &Vertex) -> Vector {
|
||||
let mut pos = vertex.position;
|
||||
for weights in vertex.bone_weights.weights() {
|
||||
if let Some(bone) = self.mdl.bones.get(weights.bone_id as usize) {
|
||||
pos = pos.transformed(bone.pose_to_bone);
|
||||
}
|
||||
}
|
||||
pos
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SkinTable<'a> {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ type Result<T> = std::result::Result<T, ModelError>;
|
|||
pub struct Mdl {
|
||||
pub name: FixedString<64>,
|
||||
pub header: StudioHeader,
|
||||
pub header2: Option<StudioHeader2>,
|
||||
pub bones: Vec<Bone>,
|
||||
pub body_parts: Vec<BodyPart>,
|
||||
pub textures: Vec<TextureInfo>,
|
||||
|
|
@ -30,6 +31,10 @@ pub struct Mdl {
|
|||
impl Mdl {
|
||||
pub fn read(data: &[u8]) -> Result<Self> {
|
||||
let header = <StudioHeader as Readable>::read(data)?;
|
||||
let header2 = header
|
||||
.header2_index()
|
||||
.map(|index| read_single(data, index))
|
||||
.transpose()?;
|
||||
let name = header.name.try_into()?;
|
||||
let mut textures = read_relative_iter(data, header.texture_indexes())
|
||||
.collect::<Result<Vec<TextureInfo>>>()?;
|
||||
|
|
@ -72,6 +77,7 @@ impl Mdl {
|
|||
texture_paths,
|
||||
skin_table,
|
||||
header,
|
||||
header2,
|
||||
surface_prop,
|
||||
key_values,
|
||||
pose_parameters,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use crate::mdl::raw::*;
|
||||
use crate::{index_range, Vector};
|
||||
use crate::mdl::StudioHeader2;
|
||||
use crate::{index_range, read_single, Vector};
|
||||
use std::mem::size_of;
|
||||
|
||||
pub const FILETYPE_ID: i32 = i32::from_be_bytes(*b"IDST");
|
||||
|
|
@ -201,7 +202,7 @@ bitflags! {
|
|||
}
|
||||
|
||||
impl StudioHeader {
|
||||
pub fn header2_index(&self) -> Option<usize> {
|
||||
pub(crate) fn header2_index(&self) -> Option<usize> {
|
||||
(self.studio_hdr2_index > 0)
|
||||
.then_some(self.studio_hdr2_index)
|
||||
.and_then(|index| usize::try_from(index).ok())
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
use crate::ReadableRelative;
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
use std::ops::Range;
|
||||
|
||||
pub struct StudioHHeader2 {
|
||||
#[derive(Debug, Clone, Copy, Zeroable, Pod)]
|
||||
#[repr(C)]
|
||||
pub struct StudioHeader2 {
|
||||
source_bone_transform_count: i32,
|
||||
source_bone_transform_index: i32,
|
||||
|
||||
|
|
@ -15,11 +19,13 @@ pub struct StudioHHeader2 {
|
|||
bone_flex_driver_count: i32,
|
||||
bone_flex_driver_index: i32,
|
||||
|
||||
#[allow(dead_code)]
|
||||
reserved: [i32; 56],
|
||||
_reserved1: [i32; 32],
|
||||
_reserved2: [i32; 24],
|
||||
}
|
||||
|
||||
impl StudioHHeader2 {
|
||||
impl ReadableRelative for StudioHeader2 {}
|
||||
|
||||
impl StudioHeader2 {
|
||||
pub fn source_bone_transforms(&self) -> Range<i32> {
|
||||
self.source_bone_transform_index
|
||||
..(self.source_bone_transform_index + self.source_bone_transform_count)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use crate::{ModelError, StringError};
|
||||
use arrayvec::ArrayString;
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
use cgmath::{Deg, Euler, Matrix3, Matrix4, Rad, Rotation3, Vector3};
|
||||
use cgmath::{Deg, Euler, Matrix3, Matrix4, Rad, Rotation3, Vector3, Vector4};
|
||||
use std::fmt;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::ops::{Add, Mul};
|
||||
|
|
@ -38,6 +38,12 @@ impl Vector {
|
|||
pub fn iter(&self) -> impl Iterator<Item = f32> {
|
||||
[self.x, self.y, self.z].into_iter()
|
||||
}
|
||||
|
||||
pub fn transformed<T: Into<Matrix4<f32>>>(&self, transform: T) -> Vector {
|
||||
let transform = transform.into();
|
||||
let transformed = transform * Vector4::new(self.x, self.y, self.z, 1.0);
|
||||
transformed.truncate().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vector> for [f32; 3] {
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ impl BoneWeights {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct BoneWeight {
|
||||
pub bone_id: u8,
|
||||
pub weight: f32,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue