use crate::*;
#[derive(Clone, Debug)]
pub struct Shape {
pub hollow: Option<bool>,
pub mass: Option<f32>,
pub density: Option<f32>,
pub physics_material: Option<Box<DefInstance<PhysicsMaterial>>>,
pub geom: ShapeGeom,
pub transform: Vec<RigidTransform>,
pub extra: Vec<Extra>,
}
impl Shape {
pub fn new(geom: impl Into<ShapeGeom>) -> Self {
Self {
hollow: Default::default(),
mass: Default::default(),
density: Default::default(),
physics_material: Default::default(),
geom: geom.into(),
transform: Default::default(),
extra: Default::default(),
}
}
}
impl XNode for Shape {
const NAME: &'static str = "shape";
fn parse(element: &Element) -> Result<Self> {
debug_assert_eq!(element.name(), Self::NAME);
let mut it = element.children().peekable();
Ok(Shape {
hollow: parse_opt("hollow", &mut it, parse_elem)?,
mass: parse_opt("mass", &mut it, parse_elem)?,
density: parse_opt("density", &mut it, parse_elem)?,
physics_material: parse_opt_many(&mut it, DefInstance::parse)?.map(Box::new),
transform: parse_list_many(&mut it, RigidTransform::parse)?,
geom: parse_one_many(&mut it, ShapeGeom::parse)?,
extra: Extra::parse_many(it)?,
})
}
}
impl XNodeWrite for Shape {
fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
let e = Self::elem().start(w)?;
ElemBuilder::opt_print("hollow", &self.hollow, w)?;
ElemBuilder::opt_print("mass", &self.mass, w)?;
ElemBuilder::opt_print("density", &self.density, w)?;
self.physics_material.write_to(w)?;
self.geom.write_to(w)?;
self.transform.write_to(w)?;
self.extra.write_to(w)?;
e.end(w)
}
}
impl CollectLocalMaps for Shape {
fn collect_local_maps<'a>(&'a self, maps: &mut LocalMaps<'a>) {
self.physics_material.collect_local_maps(maps);
}
}
#[derive(Clone, Debug)]
pub enum ShapeGeom {
Plane(Plane),
Box(BoxShape),
Sphere(Sphere),
Cylinder(Cylinder),
TaperedCylinder(TaperedCylinder),
Capsule(Capsule),
TaperedCapsule(TaperedCapsule),
Geom(Instance<Geometry>),
}
impl From<Plane> for ShapeGeom {
fn from(v: Plane) -> Self {
Self::Plane(v)
}
}
impl From<BoxShape> for ShapeGeom {
fn from(v: BoxShape) -> Self {
Self::Box(v)
}
}
impl From<Sphere> for ShapeGeom {
fn from(v: Sphere) -> Self {
Self::Sphere(v)
}
}
impl From<Cylinder> for ShapeGeom {
fn from(v: Cylinder) -> Self {
Self::Cylinder(v)
}
}
impl From<TaperedCylinder> for ShapeGeom {
fn from(v: TaperedCylinder) -> Self {
Self::TaperedCylinder(v)
}
}
impl From<Capsule> for ShapeGeom {
fn from(v: Capsule) -> Self {
Self::Capsule(v)
}
}
impl From<TaperedCapsule> for ShapeGeom {
fn from(v: TaperedCapsule) -> Self {
Self::TaperedCapsule(v)
}
}
impl From<Instance<Geometry>> for ShapeGeom {
fn from(v: Instance<Geometry>) -> Self {
Self::Geom(v)
}
}
impl ShapeGeom {
pub fn parse(e: &Element) -> Result<Option<Self>> {
match e.name() {
Plane::NAME => Ok(Some(Self::Plane(Plane::parse(e)?))),
BoxShape::NAME => Ok(Some(Self::Box(BoxShape::parse(e)?))),
Sphere::NAME => Ok(Some(Self::Sphere(Sphere::parse(e)?))),
Cylinder::NAME => Ok(Some(Self::Cylinder(Cylinder::parse(e)?))),
TaperedCylinder::NAME => Ok(Some(Self::TaperedCylinder(TaperedCylinder::parse(e)?))),
Capsule::NAME => Ok(Some(Self::Capsule(Capsule::parse(e)?))),
TaperedCapsule::NAME => Ok(Some(Self::TaperedCapsule(TaperedCapsule::parse(e)?))),
Geometry::INSTANCE => Ok(Some(Self::Geom(Instance::parse(e)?))),
_ => Ok(None),
}
}
}
impl XNodeWrite for ShapeGeom {
fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
match self {
Self::Plane(e) => e.write_to(w),
Self::Box(e) => e.write_to(w),
Self::Sphere(e) => e.write_to(w),
Self::Cylinder(e) => e.write_to(w),
Self::TaperedCylinder(e) => e.write_to(w),
Self::Capsule(e) => e.write_to(w),
Self::TaperedCapsule(e) => e.write_to(w),
Self::Geom(e) => e.write_to(w),
}
}
}
#[derive(Clone, Debug)]
pub struct Plane {
pub equation: [f32; 4],
pub extra: Vec<Extra>,
}
impl Plane {
pub fn new(equation: [f32; 4]) -> Self {
Self {
equation,
extra: vec![],
}
}
}
impl XNode for Plane {
const NAME: &'static str = "plane";
fn parse(element: &Element) -> Result<Self> {
debug_assert_eq!(element.name(), Self::NAME);
let mut it = element.children().peekable();
Ok(Plane {
equation: *parse_one("equation", &mut it, parse_array_n)?,
extra: Extra::parse_many(it)?,
})
}
}
impl XNodeWrite for Plane {
fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
let e = Self::elem().start(w)?;
ElemBuilder::print_arr("equation", &self.equation, w)?;
self.extra.write_to(w)?;
e.end(w)
}
}
#[derive(Clone, Debug)]
pub struct BoxShape {
pub half_extents: [f32; 3],
pub extra: Vec<Extra>,
}
impl BoxShape {
pub fn new(half_extents: [f32; 3]) -> Self {
Self {
half_extents,
extra: vec![],
}
}
}
impl XNode for BoxShape {
const NAME: &'static str = "box";
fn parse(element: &Element) -> Result<Self> {
debug_assert_eq!(element.name(), Self::NAME);
let mut it = element.children().peekable();
Ok(BoxShape {
half_extents: *parse_one("half_extents", &mut it, parse_array_n)?,
extra: Extra::parse_many(it)?,
})
}
}
impl XNodeWrite for BoxShape {
fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
let e = Self::elem().start(w)?;
ElemBuilder::print_arr("half_extents", &self.half_extents, w)?;
self.extra.write_to(w)?;
e.end(w)
}
}
#[derive(Clone, Debug)]
pub struct Sphere {
pub radius: f32,
pub extra: Vec<Extra>,
}
impl Sphere {
pub fn new(radius: f32) -> Self {
Self {
radius,
extra: vec![],
}
}
}
impl XNode for Sphere {
const NAME: &'static str = "sphere";
fn parse(element: &Element) -> Result<Self> {
debug_assert_eq!(element.name(), Self::NAME);
let mut it = element.children().peekable();
Ok(Sphere {
radius: parse_one("radius", &mut it, parse_elem)?,
extra: Extra::parse_many(it)?,
})
}
}
impl XNodeWrite for Sphere {
fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
let e = Self::elem().start(w)?;
ElemBuilder::print("radius", &self.radius, w)?;
self.extra.write_to(w)?;
e.end(w)
}
}
#[derive(Clone, Debug)]
pub struct Cylinder {
pub height: f32,
pub radius: [f32; 2],
pub extra: Vec<Extra>,
}
impl Cylinder {
pub fn new(height: f32, radius: [f32; 2]) -> Self {
Self {
height,
radius,
extra: vec![],
}
}
}
impl XNode for Cylinder {
const NAME: &'static str = "cylinder";
fn parse(element: &Element) -> Result<Self> {
debug_assert_eq!(element.name(), Self::NAME);
let mut it = element.children().peekable();
Ok(Cylinder {
height: parse_one("height", &mut it, parse_elem)?,
radius: *parse_one("radius", &mut it, parse_array_n)?,
extra: Extra::parse_many(it)?,
})
}
}
impl XNodeWrite for Cylinder {
fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
let e = Self::elem().start(w)?;
ElemBuilder::print("height", &self.height, w)?;
ElemBuilder::print_arr("radius", &self.radius, w)?;
self.extra.write_to(w)?;
e.end(w)
}
}
#[derive(Clone, Debug)]
pub struct TaperedCylinder {
pub height: f32,
pub radius1: [f32; 2],
pub radius2: [f32; 2],
pub extra: Vec<Extra>,
}
impl TaperedCylinder {
pub fn new(height: f32, radius1: [f32; 2], radius2: [f32; 2]) -> Self {
Self {
height,
radius1,
radius2,
extra: vec![],
}
}
}
impl XNode for TaperedCylinder {
const NAME: &'static str = "tapered_cylinder";
fn parse(element: &Element) -> Result<Self> {
debug_assert_eq!(element.name(), Self::NAME);
let mut it = element.children().peekable();
Ok(TaperedCylinder {
height: parse_one("height", &mut it, parse_elem)?,
radius1: *parse_one("radius1", &mut it, parse_array_n)?,
radius2: *parse_one("radius2", &mut it, parse_array_n)?,
extra: Extra::parse_many(it)?,
})
}
}
impl XNodeWrite for TaperedCylinder {
fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
let e = Self::elem().start(w)?;
ElemBuilder::print("height", &self.height, w)?;
ElemBuilder::print_arr("radius1", &self.radius1, w)?;
ElemBuilder::print_arr("radius2", &self.radius2, w)?;
self.extra.write_to(w)?;
e.end(w)
}
}
#[derive(Clone, Debug)]
pub struct Capsule {
pub height: f32,
pub radius: [f32; 2],
pub extra: Vec<Extra>,
}
impl Capsule {
pub fn new(height: f32, radius: [f32; 2]) -> Self {
Self {
height,
radius,
extra: vec![],
}
}
}
impl XNode for Capsule {
const NAME: &'static str = "capsule";
fn parse(element: &Element) -> Result<Self> {
debug_assert_eq!(element.name(), Self::NAME);
let mut it = element.children().peekable();
Ok(Capsule {
height: parse_one("height", &mut it, parse_elem)?,
radius: *parse_one("radius", &mut it, parse_array_n)?,
extra: Extra::parse_many(it)?,
})
}
}
impl XNodeWrite for Capsule {
fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
let e = Self::elem().start(w)?;
ElemBuilder::print("height", &self.height, w)?;
ElemBuilder::print_arr("radius", &self.radius, w)?;
self.extra.write_to(w)?;
e.end(w)
}
}
#[derive(Clone, Debug)]
pub struct TaperedCapsule {
pub height: f32,
pub radius1: [f32; 2],
pub radius2: [f32; 2],
pub extra: Vec<Extra>,
}
impl TaperedCapsule {
pub fn new(height: f32, radius1: [f32; 2], radius2: [f32; 2]) -> Self {
Self {
height,
radius1,
radius2,
extra: vec![],
}
}
}
impl XNode for TaperedCapsule {
const NAME: &'static str = "tapered_capsule";
fn parse(element: &Element) -> Result<Self> {
debug_assert_eq!(element.name(), Self::NAME);
let mut it = element.children().peekable();
Ok(TaperedCapsule {
height: parse_one("height", &mut it, parse_elem)?,
radius1: *parse_one("radius1", &mut it, parse_array_n)?,
radius2: *parse_one("radius2", &mut it, parse_array_n)?,
extra: Extra::parse_many(it)?,
})
}
}
impl XNodeWrite for TaperedCapsule {
fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
let e = Self::elem().start(w)?;
ElemBuilder::print("height", &self.height, w)?;
ElemBuilder::print_arr("radius1", &self.radius1, w)?;
ElemBuilder::print_arr("radius2", &self.radius2, w)?;
self.extra.write_to(w)?;
e.end(w)
}
}