aboutsummaryrefslogtreecommitdiff
path: root/src/classes
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-03-12 10:56:16 +0100
committermetamuffin <metamuffin@disroot.org>2025-03-12 10:56:16 +0100
commitcb9a60f45cb8438c58c2f1ecb2f59611dc5d515a (patch)
tree31330529a3b1b10a05f063bcaf245d562ed31f49 /src/classes
parentbed5904c0575a96d52f6e7fc3df95d3b772ef196 (diff)
downloadunity-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.rs6
-rw-r--r--src/classes/mod.rs9
-rw-r--r--src/classes/streaminginfo.rs22
-rw-r--r--src/classes/texture2d.rs35
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"),
}
}