diff options
author | metamuffin <metamuffin@disroot.org> | 2025-03-12 10:56:16 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2025-03-12 10:56:16 +0100 |
commit | cb9a60f45cb8438c58c2f1ecb2f59611dc5d515a (patch) | |
tree | 31330529a3b1b10a05f063bcaf245d562ed31f49 /src/classes | |
parent | bed5904c0575a96d52f6e7fc3df95d3b772ef196 (diff) | |
download | unity-tools-cb9a60f45cb8438c58c2f1ecb2f59611dc5d515a.tar unity-tools-cb9a60f45cb8438c58c2f1ecb2f59611dc5d515a.tar.bz2 unity-tools-cb9a60f45cb8438c58c2f1ecb2f59611dc5d515a.tar.zst |
extracted streaming data
Diffstat (limited to 'src/classes')
-rw-r--r-- | src/classes/assetinfo.rs | 6 | ||||
-rw-r--r-- | src/classes/mod.rs | 9 | ||||
-rw-r--r-- | src/classes/streaminginfo.rs | 22 | ||||
-rw-r--r-- | src/classes/texture2d.rs | 35 |
4 files changed, 58 insertions, 14 deletions
diff --git a/src/classes/assetinfo.rs b/src/classes/assetinfo.rs index 9679373..9fad90a 100644 --- a/src/classes/assetinfo.rs +++ b/src/classes/assetinfo.rs @@ -1,4 +1,4 @@ -use super::{gameobject::GameObject, pptr::PPtr}; +use super::{FromValue, gameobject::GameObject, pptr::PPtr}; use crate::object::Value; use anyhow::Result; use serde::Serialize; @@ -9,8 +9,8 @@ pub struct AssetInfo { pub preload_size: i32, pub asset: PPtr<GameObject>, } -impl AssetInfo { - pub fn from_value(v: Value) -> Result<Self> { +impl FromValue for AssetInfo { + fn from_value(v: Value) -> Result<Self> { let mut fields = v.as_class("AssetInfo").unwrap(); Ok(AssetInfo { preload_index: fields["preloadIndex"].as_i32().unwrap(), diff --git a/src/classes/mod.rs b/src/classes/mod.rs index be2d5da..f7b89cb 100644 --- a/src/classes/mod.rs +++ b/src/classes/mod.rs @@ -1,9 +1,10 @@ pub mod assetinfo; pub mod gameobject; pub mod pptr; +pub mod streaminginfo; +pub mod texture2d; pub mod transform; pub mod vectors; -pub mod texture2d; use crate::object::Value; use anyhow::Result; @@ -12,6 +13,8 @@ use gameobject::GameObject; use pptr::PPtr; use serde::Serialize; use std::collections::BTreeMap; +use streaminginfo::StreamingInfo; +use texture2d::Texture2D; use transform::Transform; #[derive(Debug, Serialize)] @@ -20,6 +23,8 @@ pub enum HValue { GameObject(GameObject), Transform(Transform), PPtr(PPtr), + Texture2D(Texture2D), + StreamingInfo(StreamingInfo), Pair(Box<HValue>, Box<HValue>), Value([Value; 1]), @@ -41,6 +46,8 @@ impl HValue { "AssetInfo" => Self::AssetInfo(AssetInfo::from_value(value)?), "GameObject" => Self::GameObject(GameObject::from_value(value)?), "Transform" => Self::Transform(Transform::from_value(value)?), + "Texture2D" => Self::Texture2D(Texture2D::from_value(value)?), + "StreamingInfo" => Self::StreamingInfo(StreamingInfo::from_value(value)?), _ => { let Value::Object { class, fields } = value else { unreachable!() diff --git a/src/classes/streaminginfo.rs b/src/classes/streaminginfo.rs new file mode 100644 index 0000000..3ab271d --- /dev/null +++ b/src/classes/streaminginfo.rs @@ -0,0 +1,22 @@ +use crate::object::Value; +use anyhow::Result; +use serde::Serialize; + +use super::FromValue; + +#[derive(Debug, Serialize)] +pub struct StreamingInfo { + pub offset: u32, + pub path: String, + pub size: u32, +} +impl FromValue for StreamingInfo { + fn from_value(v: Value) -> Result<Self> { + let fields = v.as_class("StreamingInfo").unwrap(); + Ok(StreamingInfo { + offset: fields["offset"].as_u32().unwrap(), + size: fields["size"].as_u32().unwrap(), + path: fields["path"].to_owned().as_string().unwrap(), + }) + } +} diff --git a/src/classes/texture2d.rs b/src/classes/texture2d.rs index 372aee7..2bc1ade 100644 --- a/src/classes/texture2d.rs +++ b/src/classes/texture2d.rs @@ -1,4 +1,4 @@ -use super::FromValue; +use super::{FromValue, streaminginfo::StreamingInfo}; use crate::object::Value; use anyhow::{Result, bail}; use image::{DynamicImage, Rgb, Rgba}; @@ -6,20 +6,21 @@ use serde::Serialize; use std::mem::transmute; #[derive(Debug, Serialize)] -pub struct Texture2d { +pub struct Texture2D { pub width: i32, pub height: i32, pub mip_count: i32, pub name: String, pub image_data: Vec<u8>, - pub texture_format: TextureFormat, + pub format: TextureFormat, pub texture_dimension: i32, + pub stream_data: StreamingInfo, } -impl FromValue for Texture2d { +impl FromValue for Texture2D { fn from_value(v: Value) -> Result<Self> { let mut fields = v.as_class("Texture2D").unwrap(); - Ok(Texture2d { + Ok(Texture2D { width: fields.remove("m_Width").unwrap().as_i32().unwrap(), height: fields.remove("m_Height").unwrap().as_i32().unwrap(), mip_count: fields.remove("m_MipCount").unwrap().as_i32().unwrap(), @@ -28,25 +29,33 @@ impl FromValue for Texture2d { .unwrap() .as_i32() .unwrap(), - texture_format: unsafe { + format: unsafe { transmute::<_, TextureFormat>( fields.remove("m_TextureFormat").unwrap().as_i32().unwrap(), ) }, name: fields.remove("m_Name").unwrap().as_string().unwrap(), image_data: fields.remove("image data").unwrap().as_typeless().unwrap(), + stream_data: fields.remove("m_StreamData").unwrap().parse().unwrap(), }) } } -impl Texture2d { +impl Texture2D { pub fn to_image(&self) -> Result<DynamicImage> { let w = self.width as usize; let h = self.height as usize; use TextureFormat::*; - match self.texture_format { - DXT5 => { + match self.format { + DXT1 | DXT3 | DXT5 => { + use texpresso::Format::*; let mut buf = vec![0u8; w * h * 4]; - texpresso::Format::Bc3.decompress(&self.image_data, w, h, &mut buf); + let format = match self.format { + DXT1 => Bc1, + DXT3 => Bc2, + DXT5 => Bc3, + _ => unreachable!(), + }; + format.decompress(&self.image_data, w, h, &mut buf); let im = image::ImageBuffer::<Rgba<u8>, Vec<_>>::from_raw(w as u32, h as u32, buf) .unwrap(); Ok(im.into()) @@ -73,6 +82,12 @@ impl Texture2d { .unwrap(); Ok(im.into()) } + RGBA32 => { + let buf = self.image_data.clone(); + let im = image::ImageBuffer::<Rgba<u8>, Vec<_>>::from_raw(w as u32, h as u32, buf) + .unwrap(); + Ok(im.into()) + } x => bail!("texture format {x:?} not supported"), } } |