aboutsummaryrefslogtreecommitdiff
path: root/src/classes
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-03-12 22:39:58 +0100
committermetamuffin <metamuffin@disroot.org>2025-03-12 22:39:58 +0100
commit5555c8bbefb4f52f5002603eb91b6c95cbdd97e4 (patch)
tree208e88359deb3cf5f7e2a4135693f12d76ad97e1 /src/classes
parent4906844cbfd2717a29b434fb7d8f90c5117fddd5 (diff)
downloadunity-tools-5555c8bbefb4f52f5002603eb91b6c95cbdd97e4.tar
unity-tools-5555c8bbefb4f52f5002603eb91b6c95cbdd97e4.tar.bz2
unity-tools-5555c8bbefb4f52f5002603eb91b6c95cbdd97e4.tar.zst
more parsing helpers
Diffstat (limited to 'src/classes')
-rw-r--r--src/classes/assetinfo.rs15
-rw-r--r--src/classes/gameobject.rs12
-rw-r--r--src/classes/mesh.rs128
-rw-r--r--src/classes/mod.rs22
-rw-r--r--src/classes/pptr.rs4
-rw-r--r--src/classes/streaminginfo.rs12
-rw-r--r--src/classes/texture2d.rs4
-rw-r--r--src/classes/transform.rs4
-rw-r--r--src/classes/vectors.rs55
9 files changed, 204 insertions, 52 deletions
diff --git a/src/classes/assetinfo.rs b/src/classes/assetinfo.rs
index 9fad90a..01c4530 100644
--- a/src/classes/assetinfo.rs
+++ b/src/classes/assetinfo.rs
@@ -1,5 +1,5 @@
-use super::{FromValue, gameobject::GameObject, pptr::PPtr};
-use crate::object::Value;
+use super::{gameobject::GameObject, pptr::PPtr};
+use crate::object::{Value, parser::FromValue};
use anyhow::Result;
use serde::Serialize;
@@ -13,14 +13,9 @@ 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(),
- preload_size: fields["preloadSize"].as_i32().unwrap(),
- asset: fields
- .remove("asset")
- .unwrap()
- .parse::<PPtr>()
- .unwrap()
- .cast(),
+ preload_index: fields.field("preloadIndex")?,
+ preload_size: fields.field("preloadSize")?,
+ asset: fields.field("asset")?,
})
}
}
diff --git a/src/classes/gameobject.rs b/src/classes/gameobject.rs
index 94436fa..bb4f19b 100644
--- a/src/classes/gameobject.rs
+++ b/src/classes/gameobject.rs
@@ -1,5 +1,5 @@
-use super::{FromValue, pptr::PPtr};
-use crate::object::Value;
+use super::pptr::PPtr;
+use crate::object::{Value, parser::FromValue};
use anyhow::Result;
use serde::Serialize;
@@ -34,10 +34,10 @@ impl FromValue for GameObject {
.unwrap()
})
.collect(),
- layer: fields["m_Layer"].as_u32().unwrap(),
- tag: fields["m_Tag"].as_u16().unwrap(),
- name: fields["m_Name"].clone().as_string().unwrap(),
- is_active: fields["m_IsActive"].as_bool().unwrap(),
+ layer: fields.field("m_Layer")?,
+ tag: fields.field("m_Tag")?,
+ name: fields.field("m_Name")?,
+ is_active: fields.field("m_IsActive")?,
})
}
}
diff --git a/src/classes/mesh.rs b/src/classes/mesh.rs
new file mode 100644
index 0000000..1d6889d
--- /dev/null
+++ b/src/classes/mesh.rs
@@ -0,0 +1,128 @@
+use super::streaminginfo::StreamingInfo;
+use crate::object::{Value, parser::FromValue};
+use anyhow::Result;
+use glam::Mat4;
+use serde::Serialize;
+
+#[derive(Debug, Serialize)]
+pub struct Mesh {
+ pub name: String,
+ pub bind_pose: Vec<Mat4>,
+ pub bone_name_hashes: Vec<u32>,
+ pub index_format: i32,
+ pub index_buffer: Vec<u8>,
+ pub sub_meshes: Vec<SubMesh>,
+ pub stream_data: StreamingInfo,
+}
+
+#[derive(Debug, Serialize)]
+pub struct SubMesh {
+ pub topology: i32,
+ pub vertex_count: u32,
+ pub base_vertex: u32,
+ pub first_byte: u32,
+ pub first_vertex: u32,
+ pub index_count: u32,
+}
+
+#[derive(Debug, Serialize)]
+pub struct VertexData {
+ pub channels: Vec<ChannelInfo>,
+ pub data_size: Vec<u8>,
+ pub vertex_count: u32,
+}
+
+#[derive(Debug, Serialize)]
+pub struct ChannelInfo {
+ pub dimension: u8,
+ pub format: u8,
+ pub offset: u8,
+ pub stream: u8,
+}
+
+impl FromValue for Mesh {
+ fn from_value(v: Value) -> Result<Self> {
+ let mut fields = v.as_class("Mesh").unwrap();
+ Ok(Mesh {
+ name: fields.remove("m_Name").unwrap().parse().unwrap(),
+ index_format: fields.remove("m_IndexFormat").unwrap().parse().unwrap(),
+ index_buffer: fields
+ .remove("m_IndexBuffer")
+ .unwrap()
+ .as_vector()
+ .unwrap()
+ .into_iter()
+ .map(|e| e.as_u8().unwrap())
+ .collect(),
+ sub_meshes: fields
+ .remove("m_SubMeshes")
+ .unwrap()
+ .as_vector()
+ .unwrap()
+ .into_iter()
+ .map(|e| e.parse().unwrap())
+ .collect(),
+ stream_data: fields.remove("m_StreamData").unwrap().parse().unwrap(),
+ bind_pose: fields
+ .remove("m_BindPose")
+ .unwrap()
+ .as_vector()
+ .unwrap()
+ .into_iter()
+ .map(|e| e.parse().unwrap())
+ .collect(),
+ bone_name_hashes: fields
+ .remove("m_BoneNameHashes")
+ .unwrap()
+ .as_vector()
+ .unwrap()
+ .into_iter()
+ .map(|e| e.parse().unwrap())
+ .collect(),
+ })
+ }
+}
+
+impl FromValue for VertexData {
+ fn from_value(v: Value) -> Result<Self> {
+ let mut fields = v.as_class("VertexData").unwrap();
+ Ok(VertexData {
+ vertex_count: fields.remove("vertexCount").unwrap().parse().unwrap(),
+ channels: fields
+ .remove("m_Channels")
+ .unwrap()
+ .as_array()
+ .unwrap()
+ .into_iter()
+ .map(|e| e.parse().unwrap())
+ .collect(),
+ data_size: fields.remove("m_DataSize").unwrap().as_typeless().unwrap(),
+ })
+ }
+}
+
+impl FromValue for ChannelInfo {
+ fn from_value(v: Value) -> Result<Self> {
+ let mut fields = v.as_class("ChannelInfo").unwrap();
+ Ok(ChannelInfo {
+ dimension: fields.remove("dimension").unwrap().parse().unwrap(),
+ format: fields.remove("format").unwrap().parse().unwrap(),
+ offset: fields.remove("offset").unwrap().parse().unwrap(),
+ stream: fields.remove("stream").unwrap().parse().unwrap(),
+ })
+ }
+}
+
+impl FromValue for SubMesh {
+ fn from_value(v: Value) -> Result<Self> {
+ let mut fields = v.as_class("SubMesh").unwrap();
+ Ok(SubMesh {
+ topology: fields.remove("topology").unwrap().parse().unwrap(),
+ vertex_count: fields.remove("vertexCount").unwrap().parse().unwrap(),
+ base_vertex: fields.remove("baseVertex").unwrap().parse().unwrap(),
+ first_byte: fields.remove("firstByte").unwrap().parse().unwrap(),
+ first_vertex: fields.remove("firstVertex").unwrap().parse().unwrap(),
+ index_count: fields.remove("indexCount").unwrap().parse().unwrap(),
+ })
+ }
+}
diff --git a/src/classes/mod.rs b/src/classes/mod.rs
index f7b89cb..501fdf9 100644
--- a/src/classes/mod.rs
+++ b/src/classes/mod.rs
@@ -1,15 +1,17 @@
pub mod assetinfo;
pub mod gameobject;
+pub mod mesh;
pub mod pptr;
pub mod streaminginfo;
pub mod texture2d;
pub mod transform;
pub mod vectors;
-use crate::object::Value;
+use crate::object::{Value, parser::FromValue};
use anyhow::Result;
use assetinfo::AssetInfo;
use gameobject::GameObject;
+use mesh::{ChannelInfo, Mesh, SubMesh, VertexData};
use pptr::PPtr;
use serde::Serialize;
use std::collections::BTreeMap;
@@ -25,6 +27,10 @@ pub enum HValue {
PPtr(PPtr),
Texture2D(Texture2D),
StreamingInfo(StreamingInfo),
+ SubMesh(SubMesh),
+ Mesh(Mesh),
+ VertexData(VertexData),
+ ChannelInfo(ChannelInfo),
Pair(Box<HValue>, Box<HValue>),
Value([Value; 1]),
@@ -48,6 +54,10 @@ impl HValue {
"Transform" => Self::Transform(Transform::from_value(value)?),
"Texture2D" => Self::Texture2D(Texture2D::from_value(value)?),
"StreamingInfo" => Self::StreamingInfo(StreamingInfo::from_value(value)?),
+ // "SubMesh" => Self::SubMesh(SubMesh::from_value(value)?),
+ "Mesh" => Self::Mesh(Mesh::from_value(value)?),
+ // "VertexData" => Self::VertexData(VertexData::from_value(value)?),
+ // "ChannelInfo" => Self::ChannelInfo(ChannelInfo::from_value(value)?),
_ => {
let Value::Object { class, fields } = value else {
unreachable!()
@@ -117,13 +127,3 @@ impl HValue {
}
}
}
-
-pub trait FromValue: Sized {
- fn from_value(v: Value) -> Result<Self>;
-}
-
-impl Value {
- pub(self) fn parse<T: FromValue>(self) -> Result<T> {
- T::from_value(self)
- }
-}
diff --git a/src/classes/pptr.rs b/src/classes/pptr.rs
index b42527d..6c7efdb 100644
--- a/src/classes/pptr.rs
+++ b/src/classes/pptr.rs
@@ -1,5 +1,5 @@
-use super::{FromValue, HValue};
-use crate::object::Value;
+use super::HValue;
+use crate::object::{Value, parser::FromValue};
use anyhow::Result;
use serde::Serialize;
use std::marker::PhantomData;
diff --git a/src/classes/streaminginfo.rs b/src/classes/streaminginfo.rs
index 1f8cadb..bb0b5e1 100644
--- a/src/classes/streaminginfo.rs
+++ b/src/classes/streaminginfo.rs
@@ -1,9 +1,7 @@
-use crate::object::Value;
+use crate::object::{Value, parser::FromValue};
use anyhow::Result;
use serde::Serialize;
-use super::FromValue;
-
#[derive(Debug, Serialize)]
pub struct StreamingInfo {
pub offset: u64,
@@ -12,11 +10,11 @@ pub struct StreamingInfo {
}
impl FromValue for StreamingInfo {
fn from_value(v: Value) -> Result<Self> {
- let fields = v.as_class("StreamingInfo").unwrap();
+ let mut fields = v.as_class("StreamingInfo").unwrap();
Ok(StreamingInfo {
- offset: fields["offset"].as_u64().unwrap(),
- size: fields["size"].as_u32().unwrap(),
- path: fields["path"].to_owned().as_string().unwrap(),
+ offset: fields.field("offset")?,
+ size: fields.field("size")?,
+ path: fields.field("path")?,
})
}
}
diff --git a/src/classes/texture2d.rs b/src/classes/texture2d.rs
index e3f3225..147cb5d 100644
--- a/src/classes/texture2d.rs
+++ b/src/classes/texture2d.rs
@@ -1,5 +1,5 @@
-use super::{FromValue, streaminginfo::StreamingInfo};
-use crate::object::Value;
+use super::streaminginfo::StreamingInfo;
+use crate::object::{Value, parser::FromValue};
use anyhow::{Result, bail};
use image::{DynamicImage, ImageBuffer, Luma, Rgb, Rgba};
use log::info;
diff --git a/src/classes/transform.rs b/src/classes/transform.rs
index b05985f..c9948d3 100644
--- a/src/classes/transform.rs
+++ b/src/classes/transform.rs
@@ -1,5 +1,5 @@
-use super::{FromValue, gameobject::GameObject, pptr::PPtr};
-use crate::object::Value;
+use super::{gameobject::GameObject, pptr::PPtr};
+use crate::object::{Value, parser::FromValue};
use anyhow::Result;
use glam::{Quat, Vec3};
use serde::Serialize;
diff --git a/src/classes/vectors.rs b/src/classes/vectors.rs
index c6e3a0d..76760bc 100644
--- a/src/classes/vectors.rs
+++ b/src/classes/vectors.rs
@@ -1,26 +1,57 @@
-use super::FromValue;
-use crate::object::Value;
-use glam::{Quat, Vec3};
+use crate::object::{Value, parser::FromValue};
+use glam::{Mat4, Quat, Vec3};
impl FromValue for Vec3 {
fn from_value(v: Value) -> anyhow::Result<Self> {
- let fields = v.as_class("Vector3f").unwrap();
+ let mut fields = v.as_class("Vector3f").unwrap();
Ok(Self {
- x: fields["x"].as_f32().unwrap(),
- y: fields["y"].as_f32().unwrap(),
- z: fields["z"].as_f32().unwrap(),
+ x: fields.field("x")?,
+ y: fields.field("y")?,
+ z: fields.field("z")?,
})
}
}
impl FromValue for Quat {
fn from_value(v: Value) -> anyhow::Result<Self> {
- let fields = v.as_class("Quaternionf").unwrap();
+ let mut fields = v.as_class("Quaternionf").unwrap();
Ok(Self::from_array([
- fields["x"].as_f32().unwrap(),
- fields["y"].as_f32().unwrap(),
- fields["z"].as_f32().unwrap(),
- fields["w"].as_f32().unwrap(),
+ fields.field("x")?,
+ fields.field("y")?,
+ fields.field("z")?,
+ fields.field("w")?,
+ ]))
+ }
+}
+
+impl FromValue for Mat4 {
+ fn from_value(v: Value) -> anyhow::Result<Self> {
+ let mut fields = v.as_class("Matrix4x4f").unwrap();
+ Ok(Self::from_cols_array_2d(&[
+ [
+ fields.field("e00")?,
+ fields.field("e01")?,
+ fields.field("e02")?,
+ fields.field("e03")?,
+ ],
+ [
+ fields.field("e10")?,
+ fields.field("e11")?,
+ fields.field("e12")?,
+ fields.field("e13")?,
+ ],
+ [
+ fields.field("e20")?,
+ fields.field("e21")?,
+ fields.field("e22")?,
+ fields.field("e23")?,
+ ],
+ [
+ fields.field("e30")?,
+ fields.field("e31")?,
+ fields.field("e32")?,
+ fields.field("e33")?,
+ ],
]))
}
}