From 01ed0f060605fd5c20a14f5510312e50869a4e2d Mon Sep 17 00:00:00 2001 From: Kayh Date: Mon, 11 Mar 2024 19:08:42 -0400 Subject: [PATCH] split physics extensions into more files --- .../src/extensions/omi_physics/export.rs | 5 +- .../src/extensions/omi_physics/import.rs | 2 +- .../src/extensions/omi_physics_body/export.rs | 77 ++++++++ .../src/extensions/omi_physics_body/import.rs | 80 ++++++++ .../src/extensions/omi_physics_body/io.rs | 187 ------------------ .../src/extensions/omi_physics_body/json.rs | 41 ++++ .../src/extensions/omi_physics_body/mod.rs | 10 +- .../extensions/omi_physics_shape/export.rs | 45 +++++ .../extensions/omi_physics_shape/import.rs | 38 ++++ .../omi_physics_shape/{io.rs => json.rs} | 87 +------- .../src/extensions/omi_physics_shape/mod.rs | 4 +- gltf_kun/tests/physics_extensions.rs | 2 +- 12 files changed, 302 insertions(+), 276 deletions(-) create mode 100644 gltf_kun/src/extensions/omi_physics_body/export.rs create mode 100644 gltf_kun/src/extensions/omi_physics_body/import.rs delete mode 100644 gltf_kun/src/extensions/omi_physics_body/io.rs create mode 100644 gltf_kun/src/extensions/omi_physics_body/json.rs create mode 100644 gltf_kun/src/extensions/omi_physics_shape/export.rs create mode 100644 gltf_kun/src/extensions/omi_physics_shape/import.rs rename gltf_kun/src/extensions/omi_physics_shape/{io.rs => json.rs} (70%) diff --git a/bevy_gltf_kun/src/extensions/omi_physics/export.rs b/bevy_gltf_kun/src/extensions/omi_physics/export.rs index 117ad51..60fe25a 100644 --- a/bevy_gltf_kun/src/extensions/omi_physics/export.rs +++ b/bevy_gltf_kun/src/extensions/omi_physics/export.rs @@ -2,7 +2,10 @@ use bevy::{ecs::system::RunSystemOnce, prelude::*}; use bevy_xpbd_3d::{parry::shape::ShapeType, prelude::*}; use gltf_kun::{ extensions::{ - omi_physics_body::{BodyType, Motion, OmiPhysicsBody}, + omi_physics_body::{ + weight::{BodyType, Motion}, + OmiPhysicsBody, + }, omi_physics_shape::{ physics_shape::{ BoxShape, CapsuleShape, Height, PhysicsShapeWeight, Radius, Size, SphereShape, diff --git a/bevy_gltf_kun/src/extensions/omi_physics/import.rs b/bevy_gltf_kun/src/extensions/omi_physics/import.rs index 1c6b32d..302f8a8 100644 --- a/bevy_gltf_kun/src/extensions/omi_physics/import.rs +++ b/bevy_gltf_kun/src/extensions/omi_physics/import.rs @@ -2,7 +2,7 @@ use bevy::prelude::*; use bevy_xpbd_3d::prelude::*; use gltf_kun::{ extensions::{ - omi_physics_body::{BodyType, OmiPhysicsBody}, + omi_physics_body::{weight::BodyType, OmiPhysicsBody}, omi_physics_shape::physics_shape::{ BoxShape, CapsuleShape, CylinderShape, PhysicsShapeWeight, SphereShape, }, diff --git a/gltf_kun/src/extensions/omi_physics_body/export.rs b/gltf_kun/src/extensions/omi_physics_body/export.rs new file mode 100644 index 0000000..04c45d8 --- /dev/null +++ b/gltf_kun/src/extensions/omi_physics_body/export.rs @@ -0,0 +1,77 @@ +use std::error::Error; + +use crate::{ + extensions::{omi_physics_shape::OmiPhysicsShape, ExtensionExport}, + graph::{gltf::document::GltfDocument, ByteNode, Property}, + io::format::gltf::GltfFormat, +}; + +use super::{ + json::{PhysicsBodyJson, ShapeRefJson}, + OmiPhysicsBody, EXTENSION_NAME, +}; + +impl ExtensionExport for OmiPhysicsBody { + fn export( + graph: &mut crate::graph::Graph, + doc: &GltfDocument, + format: &mut GltfFormat, + ) -> Result<(), Box> { + let mut added_extension = false; + + doc.nodes(graph) + .iter() + .enumerate() + .filter_map(|(i, n)| n.get_extension::(graph).map(|e| (i, e))) + .for_each(|(i, ext)| { + let weight = ext.read(graph); + + let node = format + .json + .nodes + .get_mut(i) + .expect("Node index out of bounds"); + + let extensions = node + .extensions + .get_or_insert(gltf::json::extensions::scene::Node::default()); + + let collider = ext + .collider(graph) + .iter() + .filter_map(|s| doc.get_extension::(graph).map(|e| (e, s))) + .find_map(|(e, s)| e.shapes(graph).position(|x| x == *s)) + .map(|shape| ShapeRefJson { + shape: shape as isize, + }); + + let trigger = ext + .trigger(graph) + .iter() + .filter_map(|s| doc.get_extension::(graph).map(|e| (e, s))) + .find_map(|(e, s)| e.shapes(graph).position(|x| x == *s)) + .map(|shape| ShapeRefJson { + shape: shape as isize, + }); + + let json = PhysicsBodyJson { + collider, + trigger, + motion: weight.motion, + }; + + extensions.others.insert( + EXTENSION_NAME.to_string(), + serde_json::to_value(json).expect("Failed to serialize extension"), + ); + + added_extension = true; + }); + + if added_extension { + format.json.extensions_used.push(EXTENSION_NAME.to_string()); + } + + Ok(()) + } +} diff --git a/gltf_kun/src/extensions/omi_physics_body/import.rs b/gltf_kun/src/extensions/omi_physics_body/import.rs new file mode 100644 index 0000000..ef13fe1 --- /dev/null +++ b/gltf_kun/src/extensions/omi_physics_body/import.rs @@ -0,0 +1,80 @@ +use std::error::Error; + +use tracing::warn; + +use crate::{ + extensions::{omi_physics_shape::OmiPhysicsShape, ExtensionImport}, + graph::{gltf::document::GltfDocument, ByteNode, Property}, + io::format::gltf::GltfFormat, +}; + +use super::{json::PhysicsBodyJson, OmiPhysicsBody, OmiPhysicsBodyWeight, EXTENSION_NAME}; + +impl ExtensionImport for OmiPhysicsBody { + fn import( + graph: &mut crate::graph::Graph, + format: &mut GltfFormat, + doc: &GltfDocument, + ) -> Result<(), Box> { + format + .json + .nodes + .iter() + .enumerate() + .filter_map(|(i, n)| n.extensions.as_ref().map(|e| (i, e))) + .filter_map(|(i, e)| e.others.get(EXTENSION_NAME).map(|v| (i, v))) + .filter_map(|(i, v)| { + serde_json::from_value::(v.clone()) + .map(|json| (i, json)) + .ok() + }) + .for_each(|(i, json)| { + let nodes = doc.nodes(graph); + let node = nodes.get(i).expect("Node index out of bounds"); + let ext = node.create_extension::(graph); + + if let Some(motion) = json.motion { + let weight = OmiPhysicsBodyWeight { + motion: Some(motion), + }; + ext.write(graph, &weight); + } + + if json.collider.is_none() && json.trigger.is_none() { + return; + } + + let omi_physics_shapes = match doc.get_extension::(graph) { + Some(ext) => ext, + None => { + warn!("OMI_physics_shape extension not found"); + return; + } + }; + + if let Some(shape_ref) = json.collider { + if let Ok(idx) = shape_ref.shape.try_into() { + let shape = omi_physics_shapes + .shapes(graph) + .nth(idx) + .expect("Collider index out of bounds"); + + ext.set_collider(graph, Some(shape)); + } + } + + if let Some(shape_ref) = json.trigger { + if let Ok(idx) = shape_ref.shape.try_into() { + let shape = omi_physics_shapes + .shapes(graph) + .nth(idx) + .expect("Trigger index out of bounds"); + + ext.set_trigger(graph, Some(shape)); + } + } + }); + + Ok(()) + } +} diff --git a/gltf_kun/src/extensions/omi_physics_body/io.rs b/gltf_kun/src/extensions/omi_physics_body/io.rs deleted file mode 100644 index 1f4c51b..0000000 --- a/gltf_kun/src/extensions/omi_physics_body/io.rs +++ /dev/null @@ -1,187 +0,0 @@ -use std::error::Error; - -use serde::{Deserialize, Serialize}; -use tracing::warn; - -use crate::{ - extensions::{omi_physics_shape::OmiPhysicsShape, ExtensionExport, ExtensionImport}, - graph::{gltf::document::GltfDocument, ByteNode, Property}, - io::format::gltf::GltfFormat, -}; - -use super::{Motion, OmiPhysicsBody, OmiPhysicsBodyWeight, EXTENSION_NAME}; - -#[derive(Debug, Deserialize, PartialEq, Serialize)] -pub struct PhysicsBodyJson { - #[serde(default, skip_serializing_if = "Option::is_none")] - collider: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - motion: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - trigger: Option, -} - -#[derive(Debug, Deserialize, PartialEq, Serialize)] -pub struct ShapeRefJson { - pub shape: isize, -} - -impl ExtensionExport for OmiPhysicsBody { - fn export( - graph: &mut crate::graph::Graph, - doc: &GltfDocument, - format: &mut GltfFormat, - ) -> Result<(), Box> { - let mut added_extension = false; - - doc.nodes(graph) - .iter() - .enumerate() - .filter_map(|(i, n)| n.get_extension::(graph).map(|e| (i, e))) - .for_each(|(i, ext)| { - let weight = ext.read(graph); - - let node = format - .json - .nodes - .get_mut(i) - .expect("Node index out of bounds"); - - let extensions = node - .extensions - .get_or_insert(gltf::json::extensions::scene::Node::default()); - - let collider = ext - .collider(graph) - .iter() - .filter_map(|s| doc.get_extension::(graph).map(|e| (e, s))) - .find_map(|(e, s)| e.shapes(graph).position(|x| x == *s)) - .map(|shape| ShapeRefJson { - shape: shape as isize, - }); - - let trigger = ext - .trigger(graph) - .iter() - .filter_map(|s| doc.get_extension::(graph).map(|e| (e, s))) - .find_map(|(e, s)| e.shapes(graph).position(|x| x == *s)) - .map(|shape| ShapeRefJson { - shape: shape as isize, - }); - - let json = PhysicsBodyJson { - collider, - trigger, - motion: weight.motion, - }; - - extensions.others.insert( - EXTENSION_NAME.to_string(), - serde_json::to_value(json).expect("Failed to serialize extension"), - ); - - added_extension = true; - }); - - if added_extension { - format.json.extensions_used.push(EXTENSION_NAME.to_string()); - } - - Ok(()) - } -} - -impl ExtensionImport for OmiPhysicsBody { - fn import( - graph: &mut crate::graph::Graph, - format: &mut GltfFormat, - doc: &GltfDocument, - ) -> Result<(), Box> { - format - .json - .nodes - .iter() - .enumerate() - .filter_map(|(i, n)| n.extensions.as_ref().map(|e| (i, e))) - .filter_map(|(i, e)| e.others.get(EXTENSION_NAME).map(|v| (i, v))) - .filter_map(|(i, v)| { - serde_json::from_value::(v.clone()) - .map(|json| (i, json)) - .ok() - }) - .for_each(|(i, json)| { - let nodes = doc.nodes(graph); - let node = nodes.get(i).expect("Node index out of bounds"); - let ext = node.create_extension::(graph); - - // Motion - if let Some(motion) = json.motion { - let weight = OmiPhysicsBodyWeight { - motion: Some(motion), - }; - ext.write(graph, &weight); - } - - if json.collider.is_none() && json.trigger.is_none() { - return; - } - - let omi_physics_shapes = match doc.get_extension::(graph) { - Some(ext) => ext, - None => { - warn!("OMI_physics_shape extension not found"); - return; - } - }; - - // Collider - if let Some(shape_ref) = json.collider { - if let Ok(idx) = shape_ref.shape.try_into() { - let shape = omi_physics_shapes - .shapes(graph) - .nth(idx) - .expect("Collider index out of bounds"); - - ext.set_collider(graph, Some(shape)); - } - } - - // Trigger - if let Some(shape_ref) = json.trigger { - if let Ok(idx) = shape_ref.shape.try_into() { - let shape = omi_physics_shapes - .shapes(graph) - .nth(idx) - .expect("Trigger index out of bounds"); - - ext.set_trigger(graph, Some(shape)); - } - } - }); - - Ok(()) - } -} - -#[cfg(test)] -mod tests { - use crate::extensions::omi_physics_body::weight::{BodyType, Motion}; - - use super::*; - - #[test] - fn motion_serde() { - let json = PhysicsBodyJson { - motion: Some(Motion::new(BodyType::Dynamic)), - trigger: None, - collider: None, - }; - - let json_str = serde_json::to_string(&json).unwrap(); - let expected = r#"{"motion":{"type":"dynamic"}}"#; - assert_eq!(json_str, expected); - - let json_2 = serde_json::from_str::(&json_str).unwrap(); - assert_eq!(json, json_2); - } -} diff --git a/gltf_kun/src/extensions/omi_physics_body/json.rs b/gltf_kun/src/extensions/omi_physics_body/json.rs new file mode 100644 index 0000000..7cc2ab6 --- /dev/null +++ b/gltf_kun/src/extensions/omi_physics_body/json.rs @@ -0,0 +1,41 @@ +use serde::{Deserialize, Serialize}; + +use super::weight::Motion; + +#[derive(Debug, Deserialize, PartialEq, Serialize)] +pub struct PhysicsBodyJson { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub collider: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub motion: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub trigger: Option, +} + +#[derive(Debug, Deserialize, PartialEq, Serialize)] +pub struct ShapeRefJson { + pub shape: isize, +} + +#[cfg(test)] +mod tests { + use crate::extensions::omi_physics_body::weight::{BodyType, Motion}; + + use super::*; + + #[test] + fn motion_serde() { + let json = PhysicsBodyJson { + motion: Some(Motion::new(BodyType::Dynamic)), + trigger: None, + collider: None, + }; + + let json_str = serde_json::to_string(&json).unwrap(); + let expected = r#"{"motion":{"type":"dynamic"}}"#; + assert_eq!(json_str, expected); + + let json_2 = serde_json::from_str::(&json_str).unwrap(); + assert_eq!(json, json_2); + } +} diff --git a/gltf_kun/src/extensions/omi_physics_body/mod.rs b/gltf_kun/src/extensions/omi_physics_body/mod.rs index 8254fc9..017c525 100644 --- a/gltf_kun/src/extensions/omi_physics_body/mod.rs +++ b/gltf_kun/src/extensions/omi_physics_body/mod.rs @@ -6,12 +6,14 @@ use serde::{Deserialize, Serialize}; use crate::graph::{ByteNode, Graph, OtherEdgeHelpers}; -use super::{omi_physics_shape::physics_shape::PhysicsShape, Extension}; +use self::weight::OmiPhysicsBodyWeight; -pub mod io; -mod weight; +use super::{omi_physics_shape::physics_shape::PhysicsShape, Extension}; -pub use weight::*; +pub mod export; +pub mod import; +pub mod json; +pub mod weight; pub const EXTENSION_NAME: &str = "OMI_physics_body"; diff --git a/gltf_kun/src/extensions/omi_physics_shape/export.rs b/gltf_kun/src/extensions/omi_physics_shape/export.rs new file mode 100644 index 0000000..234c4df --- /dev/null +++ b/gltf_kun/src/extensions/omi_physics_shape/export.rs @@ -0,0 +1,45 @@ +use crate::{ + extensions::ExtensionExport, + graph::{gltf::document::GltfDocument, ByteNode, Graph, Property}, + io::format::gltf::GltfFormat, +}; + +use super::{json::RootExtension, OmiPhysicsShape, EXTENSION_NAME}; + +impl ExtensionExport for OmiPhysicsShape { + fn export( + graph: &mut Graph, + doc: &GltfDocument, + format: &mut GltfFormat, + ) -> Result<(), Box> { + let ext = match doc.get_extension::(graph) { + Some(ext) => ext, + None => return Ok(()), + }; + + let shapes = ext + .shapes(graph) + .map(|shape| shape.read(graph).into()) + .collect::>(); + + if shapes.is_empty() { + return Ok(()); + } + + let root_extension = RootExtension { shapes }; + + let extensions = format + .json + .extensions + .get_or_insert(gltf::json::extensions::Root::default()); + + extensions.others.insert( + EXTENSION_NAME.to_string(), + serde_json::to_value(root_extension)?, + ); + + format.json.extensions_used.push(EXTENSION_NAME.to_string()); + + Ok(()) + } +} diff --git a/gltf_kun/src/extensions/omi_physics_shape/import.rs b/gltf_kun/src/extensions/omi_physics_shape/import.rs new file mode 100644 index 0000000..f52f250 --- /dev/null +++ b/gltf_kun/src/extensions/omi_physics_shape/import.rs @@ -0,0 +1,38 @@ +use crate::{ + extensions::ExtensionImport, + graph::{gltf::document::GltfDocument, Graph, Property}, + io::format::gltf::GltfFormat, +}; + +use super::{json::RootExtension, OmiPhysicsShape, EXTENSION_NAME}; + +impl ExtensionImport for OmiPhysicsShape { + fn import( + graph: &mut Graph, + format: &mut GltfFormat, + doc: &GltfDocument, + ) -> Result<(), Box> { + let extensions = match &format.json.extensions { + Some(extensions) => extensions, + None => return Ok(()), + }; + + let value = match extensions.others.get(EXTENSION_NAME) { + Some(extension) => extension, + None => return Ok(()), + }; + + let root_extension = serde_json::from_value::(value.clone())?; + + let ext = match doc.get_extension::(graph) { + Some(ext) => ext, + None => doc.create_extension::(graph), + }; + + root_extension.shapes.iter().for_each(|shape| { + ext.create_shape(graph, &shape.weight); + }); + + Ok(()) + } +} diff --git a/gltf_kun/src/extensions/omi_physics_shape/io.rs b/gltf_kun/src/extensions/omi_physics_shape/json.rs similarity index 70% rename from gltf_kun/src/extensions/omi_physics_shape/io.rs rename to gltf_kun/src/extensions/omi_physics_shape/json.rs index 06cd5e8..0f79aea 100644 --- a/gltf_kun/src/extensions/omi_physics_shape/io.rs +++ b/gltf_kun/src/extensions/omi_physics_shape/json.rs @@ -1,22 +1,16 @@ use serde::{Deserialize, Serialize}; -use crate::{ - extensions::{ExtensionExport, ExtensionImport}, - graph::{gltf::document::GltfDocument, ByteNode, Graph, Property}, - io::format::gltf::GltfFormat, -}; - -use super::{physics_shape::PhysicsShapeWeight, OmiPhysicsShape, EXTENSION_NAME}; +use super::physics_shape::PhysicsShapeWeight; #[derive(Debug, Deserialize, Serialize)] -struct RootExtension { - shapes: Vec, +pub struct RootExtension { + pub shapes: Vec, } #[derive(Debug, Deserialize, Serialize)] -struct Shape { +pub struct Shape { #[serde(rename = "type", skip_deserializing)] - typ: String, + pub typ: String, #[serde( alias = "box", alias = "sphere", @@ -26,7 +20,7 @@ struct Shape { alias = "trimesh", flatten )] - weight: PhysicsShapeWeight, + pub weight: PhysicsShapeWeight, } impl From for Shape { @@ -47,75 +41,6 @@ impl From for Shape { } } -impl ExtensionExport for OmiPhysicsShape { - fn export( - graph: &mut Graph, - doc: &GltfDocument, - format: &mut GltfFormat, - ) -> Result<(), Box> { - let ext = match doc.get_extension::(graph) { - Some(ext) => ext, - None => return Ok(()), - }; - - let shapes = ext - .shapes(graph) - .map(|shape| shape.read(graph).into()) - .collect::>(); - - if shapes.is_empty() { - return Ok(()); - } - - let root_extension = RootExtension { shapes }; - - let extensions = format - .json - .extensions - .get_or_insert(gltf::json::extensions::Root::default()); - - extensions.others.insert( - EXTENSION_NAME.to_string(), - serde_json::to_value(root_extension)?, - ); - - format.json.extensions_used.push(EXTENSION_NAME.to_string()); - - Ok(()) - } -} - -impl ExtensionImport for OmiPhysicsShape { - fn import( - graph: &mut Graph, - format: &mut GltfFormat, - doc: &GltfDocument, - ) -> Result<(), Box> { - let extensions = match &format.json.extensions { - Some(extensions) => extensions, - None => return Ok(()), - }; - - let value = match extensions.others.get(EXTENSION_NAME) { - Some(extension) => extension, - None => return Ok(()), - }; - - let root_extension = serde_json::from_value::(value.clone())?; - - let ext = match doc.get_extension::(graph) { - Some(ext) => ext, - None => doc.create_extension::(graph), - }; - - root_extension.shapes.iter().for_each(|shape| { - ext.create_shape(graph, &shape.weight); - }); - - Ok(()) - } -} - #[cfg(test)] mod tests { use crate::extensions::omi_physics_shape::physics_shape::{ diff --git a/gltf_kun/src/extensions/omi_physics_shape/mod.rs b/gltf_kun/src/extensions/omi_physics_shape/mod.rs index d117902..dd35bde 100644 --- a/gltf_kun/src/extensions/omi_physics_shape/mod.rs +++ b/gltf_kun/src/extensions/omi_physics_shape/mod.rs @@ -8,7 +8,9 @@ use self::physics_shape::{PhysicsShape, PhysicsShapeWeight}; use super::Extension; -pub mod io; +pub mod export; +pub mod import; +pub mod json; pub mod physics_shape; pub const EXTENSION_NAME: &str = "OMI_physics_shape"; diff --git a/gltf_kun/tests/physics_extensions.rs b/gltf_kun/tests/physics_extensions.rs index 7621e2d..671c96a 100644 --- a/gltf_kun/tests/physics_extensions.rs +++ b/gltf_kun/tests/physics_extensions.rs @@ -2,7 +2,7 @@ use std::path::Path; use gltf_kun::{ extensions::{ - omi_physics_body::{BodyType, OmiPhysicsBody}, + omi_physics_body::{weight::BodyType, OmiPhysicsBody}, omi_physics_shape::{ physics_shape::{BoxShape, PhysicsShapeWeight, Size}, OmiPhysicsShape,