use anyhow::Result;
use crate::sdf::Path;
use crate::usd::{Prim, Stage};
use crate::schemas::physics::tokens::{A_GRAVITY_DIRECTION, A_GRAVITY_MAGNITUDE, T_PHYSICS_SCENE};
use super::common::{author_float, author_vector3f};
pub fn define_physics_scene<'s>(stage: &'s Stage, path: impl Into<Path>) -> Result<PhysicsSceneAuthor<'s>> {
let prim = stage.define_prim(path)?.set_type_name(T_PHYSICS_SCENE)?;
Ok(PhysicsSceneAuthor { prim })
}
pub struct PhysicsSceneAuthor<'s> {
prim: Prim<'s>,
}
impl<'s> PhysicsSceneAuthor<'s> {
pub fn into_prim(self) -> Prim<'s> {
self.prim
}
pub fn set_gravity_direction(self, direction: [f32; 3]) -> Result<Self> {
author_vector3f(self.prim.stage(), self.prim.path(), A_GRAVITY_DIRECTION, direction)?;
Ok(self)
}
pub fn set_gravity_magnitude(self, magnitude: f32) -> Result<Self> {
author_float(self.prim.stage(), self.prim.path(), A_GRAVITY_MAGNITUDE, magnitude)?;
Ok(self)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sdf;
#[test]
fn physics_scene_roundtrip() -> Result<()> {
let stage = Stage::builder().in_memory("anon.usda")?;
define_physics_scene(&stage, sdf::path("/Scene")?)?
.set_gravity_direction([0.0, -1.0, 0.0])?
.set_gravity_magnitude(9.81)?;
let scene = crate::schemas::physics::read_physics_scene(&stage, &sdf::path("/Scene")?)?.expect("PhysicsScene");
assert_eq!(scene.gravity_direction, Some([0.0, -1.0, 0.0]));
assert!((scene.gravity_magnitude.unwrap() - 9.81).abs() < 1e-3);
Ok(())
}
}