Add support for viewing WMDL and SMDL files

This commit is contained in:
Phillip Stephens
2023-03-04 18:36:39 -08:00
parent 32ed510fcb
commit 972b05fbd2
3 changed files with 24 additions and 7 deletions
+20 -3
View File
@@ -14,9 +14,15 @@ use crate::{
// Cooked model
pub const K_FORM_CMDL: FourCC = FourCC(*b"CMDL");
pub const K_FORM_SMDL: FourCC = FourCC(*b"SMDL");
pub const K_FORM_WMDL: FourCC = FourCC(*b"WMDL");
// Model header
pub const K_CHUNK_HEAD: FourCC = FourCC(*b"HEAD");
// World header
pub const K_CHUNK_WDHD: FourCC = FourCC(*b"WDHD");
// Skinned header
pub const K_CHUNK_SKHD: FourCC = FourCC(*b"SKHD");
// Material data
pub const K_CHUNK_MTRL: FourCC = FourCC(*b"MTRL");
// Mesh data
@@ -776,9 +782,18 @@ pub struct ModelData {
impl ModelData {
pub fn slice(data: &[u8], meta: &[u8], e: Endian) -> Result<ModelData> {
let (cmdl_desc, mut cmdl_data, _) = FormDescriptor::slice(data, Endian::Little)?;
ensure!(cmdl_desc.id == K_FORM_CMDL);
ensure!(cmdl_desc.version_a == 114);
ensure!(cmdl_desc.version_b == 125);
ensure!(cmdl_desc.id == K_FORM_CMDL || cmdl_desc.id == K_FORM_SMDL || cmdl_desc.id == K_FORM_WMDL);
if cmdl_desc.id == K_FORM_CMDL {
ensure!(cmdl_desc.version_a == 114);
ensure!(cmdl_desc.version_b == 125);
} else if cmdl_desc.id == K_FORM_SMDL {
ensure!(cmdl_desc.version_a == 127);
ensure!(cmdl_desc.version_b == 133);
} else if cmdl_desc.id == K_FORM_WMDL {
ensure!(cmdl_desc.version_a == 118);
ensure!(cmdl_desc.version_b == 124);
}
let meta: SModelMetaData = Cursor::new(meta).read_type(e)?;
let vtx_buffers = decompress_gpu_buffers(data, &meta.read_info, &meta.vtx_buffer_info)?;
@@ -792,6 +807,8 @@ impl ModelData {
while !cmdl_data.is_empty() {
let (chunk_desc, chunk_data, remain) = ChunkDescriptor::slice(cmdl_data, e)?;
match chunk_desc.id {
K_CHUNK_WDHD => head = Some(Cursor::new(chunk_data).read_type(e)?),
K_CHUNK_SKHD => head = Some(Cursor::new(chunk_data).read_type(e)?),
K_CHUNK_HEAD => head = Some(Cursor::new(chunk_data).read_type(e)?),
K_CHUNK_MTRL => mtrl = Some(Cursor::new(chunk_data).read_type(e)?),
K_CHUNK_MESH => mesh = Some(Cursor::new(chunk_data).read_type(e)?),
+1 -1
View File
@@ -297,7 +297,7 @@ impl AssetLoader for ModelAssetLoader {
})
}
fn extensions(&self) -> &[&str] { &["cmdl"] }
fn extensions(&self) -> &[&str] { &["cmdl", "smdl", "wmdl"] }
}
#[derive(Debug, Clone, bevy::reflect::TypeUuid)]
+3 -3
View File
@@ -3,7 +3,7 @@ use bevy::{
prelude::*,
};
use egui::{text::LayoutJob, Color32, TextFormat, Widget};
use retrolib::format::{cmdl::K_FORM_CMDL, txtr::K_FORM_TXTR, FourCC};
use retrolib::format::{cmdl::{K_FORM_CMDL, K_FORM_SMDL, K_FORM_WMDL}, txtr::K_FORM_TXTR, FourCC};
use crate::{
icon,
@@ -41,7 +41,7 @@ impl SystemTab for ProjectTab {
"{} {} {}",
match entry.kind {
K_FORM_TXTR => icon::TEXTURE,
K_FORM_CMDL => icon::FILE_3D,
K_FORM_CMDL | K_FORM_SMDL | K_FORM_WMDL => icon::FILE_3D,
K_FORM_FMV0 => icon::FILE_MOVIE,
K_FORM_ROOM => icon::SCENE_DATA,
_ => icon::FILE,
@@ -77,7 +77,7 @@ impl SystemTab for ProjectTab {
loaded_texture: None,
}));
}
K_FORM_CMDL => {
K_FORM_CMDL | K_FORM_SMDL | K_FORM_WMDL => {
let handle = server
.load::<ModelAsset, _>(format!("{}.{}", entry.id, entry.kind));
state.open_tab = Some(TabType::Model(ModelTab {