aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock10
-rw-r--r--Cargo.toml1
-rw-r--r--src/classes/assetinfo.rs5
-rw-r--r--src/classes/gameobject.rs25
-rw-r--r--src/classes/mod.rs12
-rw-r--r--src/classes/pptr.rs9
-rw-r--r--src/classes/transform.rs26
-rw-r--r--src/classes/vectors.rs26
-rw-r--r--src/object.rs7
9 files changed, 102 insertions, 19 deletions
diff --git a/Cargo.lock b/Cargo.lock
index c7d676c..9fbbfa8 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -115,6 +115,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
+name = "glam"
+version = "0.30.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "17fcdf9683c406c2fc4d124afd29c0d595e22210d633cbdb8695ba9935ab1dc6"
+dependencies = [
+ "serde",
+]
+
+[[package]]
name = "hashbrown"
version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -348,6 +357,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"env_logger",
+ "glam",
"humansize",
"log",
"lz4_flex",
diff --git a/Cargo.toml b/Cargo.toml
index 7a7bd59..4ee13fe 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,3 +13,4 @@ serde_json = "1.0.139"
humansize = "2.1.3"
serde = { version = "1.0.219", features = ["derive"] }
serde_yml = "0.0.12"
+glam = { version = "0.30.0", features = ["serde"] }
diff --git a/src/classes/assetinfo.rs b/src/classes/assetinfo.rs
index dadcea3..9679373 100644
--- a/src/classes/assetinfo.rs
+++ b/src/classes/assetinfo.rs
@@ -15,7 +15,10 @@ impl AssetInfo {
Ok(AssetInfo {
preload_index: fields["preloadIndex"].as_i32().unwrap(),
preload_size: fields["preloadSize"].as_i32().unwrap(),
- asset: PPtr::from_value(fields.remove("asset").unwrap())
+ asset: fields
+ .remove("asset")
+ .unwrap()
+ .parse::<PPtr>()
.unwrap()
.cast(),
})
diff --git a/src/classes/gameobject.rs b/src/classes/gameobject.rs
index fde042d..94436fa 100644
--- a/src/classes/gameobject.rs
+++ b/src/classes/gameobject.rs
@@ -1,7 +1,7 @@
+use super::{FromValue, pptr::PPtr};
+use crate::object::Value;
use anyhow::Result;
use serde::Serialize;
-use crate::object::Value;
-use super::pptr::PPtr;
#[derive(Debug, Serialize)]
pub struct GameObject {
@@ -11,24 +11,27 @@ pub struct GameObject {
pub name: String,
pub is_active: bool,
}
-impl GameObject {
- pub fn from_value(v: Value) -> Result<Self> {
+impl FromValue for GameObject {
+ fn from_value(v: Value) -> Result<Self> {
let mut fields = v.as_class("GameObject").unwrap();
Ok(GameObject {
components: fields
.remove("m_Component")
.unwrap()
+ .as_class("vector")
+ .unwrap()
+ .remove("Array")
+ .unwrap()
.as_array()
.unwrap()
.into_iter()
.map(|e| {
- PPtr::from_value(
- e.as_class("ComponentPair")
- .unwrap()
- .remove("component")
- .unwrap(),
- )
- .unwrap()
+ e.as_class("ComponentPair")
+ .unwrap()
+ .remove("component")
+ .unwrap()
+ .parse::<PPtr>()
+ .unwrap()
})
.collect(),
layer: fields["m_Layer"].as_u32().unwrap(),
diff --git a/src/classes/mod.rs b/src/classes/mod.rs
index bfde8ad..8c0db51 100644
--- a/src/classes/mod.rs
+++ b/src/classes/mod.rs
@@ -2,6 +2,7 @@ pub mod assetinfo;
pub mod gameobject;
pub mod pptr;
pub mod transform;
+pub mod vectors;
use crate::object::Value;
use anyhow::Result;
@@ -38,6 +39,7 @@ impl HValue {
x if x.starts_with("PPtr<") => Self::PPtr(PPtr::from_value(value)?),
"AssetInfo" => Self::AssetInfo(AssetInfo::from_value(value)?),
"GameObject" => Self::GameObject(GameObject::from_value(value)?),
+ "Transform" => Self::Transform(Transform::from_value(value)?),
_ => {
let Value::Object { class, fields } = value else {
unreachable!()
@@ -107,3 +109,13 @@ impl HValue {
}
}
}
+
+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 1f615ab..b42527d 100644
--- a/src/classes/pptr.rs
+++ b/src/classes/pptr.rs
@@ -1,4 +1,4 @@
-use super::HValue;
+use super::{FromValue, HValue};
use crate::object::Value;
use anyhow::Result;
use serde::Serialize;
@@ -6,13 +6,14 @@ use std::marker::PhantomData;
#[derive(Debug, Serialize)]
pub struct PPtr<T = HValue> {
+ #[serde(skip, default)]
_class: PhantomData<T>,
pub class: String,
pub file_id: i32,
pub path_id: i64,
}
-impl PPtr {
- pub fn from_value(v: Value) -> Result<Self> {
+impl<T> FromValue for PPtr<T> {
+ fn from_value(v: Value) -> Result<Self> {
let Value::Object { class, fields } = v else {
unreachable!()
};
@@ -28,6 +29,8 @@ impl PPtr {
path_id: fields["m_PathID"].as_i64().unwrap(),
})
}
+}
+impl PPtr {
pub fn cast<T>(self) -> PPtr<T> {
PPtr {
_class: PhantomData,
diff --git a/src/classes/transform.rs b/src/classes/transform.rs
index 518e248..b05985f 100644
--- a/src/classes/transform.rs
+++ b/src/classes/transform.rs
@@ -1,26 +1,44 @@
-use super::pptr::PPtr;
+use super::{FromValue, gameobject::GameObject, pptr::PPtr};
use crate::object::Value;
use anyhow::Result;
+use glam::{Quat, Vec3};
use serde::Serialize;
#[derive(Debug, Serialize)]
pub struct Transform {
pub father: PPtr<Transform>,
pub children: Vec<PPtr<Transform>>,
+ pub gameobject: PPtr<GameObject>,
+ pub local_position: Vec3,
+ pub local_rotation: Quat,
+ pub local_scale: Vec3,
}
-impl Transform {
- pub fn from_value(v: Value) -> Result<Self> {
+impl FromValue for Transform {
+ fn from_value(v: Value) -> Result<Self> {
let mut fields = v.as_class("Transform").unwrap();
Ok(Self {
children: fields
.remove("m_Children")
.unwrap()
+ .as_class("vector")
+ .unwrap()
+ .remove("Array")
+ .unwrap()
.as_array()
.unwrap()
.into_iter()
.map(|e| PPtr::from_value(e).unwrap().cast())
.collect(),
- father: PPtr::from_value(fields.remove("m_Father").unwrap())?.cast(),
+ father: fields
+ .remove("m_Father")
+ .unwrap()
+ .parse::<PPtr>()
+ .unwrap()
+ .cast(),
+ gameobject: fields.remove("m_GameObject").unwrap().parse().unwrap(),
+ local_position: fields.remove("m_LocalPosition").unwrap().parse().unwrap(),
+ local_rotation: fields.remove("m_LocalRotation").unwrap().parse().unwrap(),
+ local_scale: fields.remove("m_LocalScale").unwrap().parse().unwrap(),
})
}
}
diff --git a/src/classes/vectors.rs b/src/classes/vectors.rs
new file mode 100644
index 0000000..c6e3a0d
--- /dev/null
+++ b/src/classes/vectors.rs
@@ -0,0 +1,26 @@
+use super::FromValue;
+use crate::object::Value;
+use glam::{Quat, Vec3};
+
+impl FromValue for Vec3 {
+ fn from_value(v: Value) -> anyhow::Result<Self> {
+ let 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(),
+ })
+ }
+}
+
+impl FromValue for Quat {
+ fn from_value(v: Value) -> anyhow::Result<Self> {
+ let 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(),
+ ]))
+ }
+}
diff --git a/src/object.rs b/src/object.rs
index 0068fc2..9387721 100644
--- a/src/object.rs
+++ b/src/object.rs
@@ -164,6 +164,13 @@ impl Value {
None
}
}
+ pub fn as_f32(&self) -> Option<f32> {
+ if let Value::F32(s) = self {
+ Some(*s)
+ } else {
+ None
+ }
+ }
pub fn as_u16(&self) -> Option<u16> {
if let Value::U16(s) = self {
Some(*s)