use crate::assets::Assets;
use crate::body::Body;
use crate::compiler::{Compiler, SimOption};
use crate::contact::Contact;
use crate::equality::Equality;
use crate::extras::{Actuator, Keyframe, Sensor};
pub type BodyId = usize;
#[derive(Clone, Debug, Default)]
pub struct Model {
pub name: Option<String>,
pub compiler: Compiler,
pub option: SimOption,
pub assets: Assets,
pub bodies: Vec<BodyEntry>,
pub contact: Contact,
pub equality: Vec<Equality>,
pub actuators: Vec<Actuator>,
pub sensors: Vec<Sensor>,
pub keyframes: Vec<Keyframe>,
pub tendons: Vec<crate::tendon::FixedTendon>,
}
#[derive(Clone, Debug)]
pub struct BodyEntry {
pub parent: Option<BodyId>,
pub body: Body,
}
impl Model {
pub fn bodies_iter(&self) -> impl Iterator<Item = (BodyId, &BodyEntry)> {
self.bodies.iter().enumerate().filter(|(id, _)| *id != 0)
}
pub fn body_id_by_name(&self, name: &str) -> Option<BodyId> {
self.bodies
.iter()
.position(|e| e.body.name.as_deref() == Some(name))
}
pub fn geom_by_name(&self, name: &str) -> Option<(BodyId, usize)> {
for (bi, e) in self.bodies.iter().enumerate() {
for (gi, g) in e.body.geoms.iter().enumerate() {
if g.name.as_deref() == Some(name) {
return Some((bi, gi));
}
}
}
None
}
pub fn joint_by_name(&self, name: &str) -> Option<(BodyId, usize)> {
for (bi, e) in self.bodies.iter().enumerate() {
for (ji, j) in e.body.joints.iter().enumerate() {
if j.name.as_deref() == Some(name) {
return Some((bi, ji));
}
}
}
None
}
pub fn site_by_name(&self, name: &str) -> Option<(BodyId, usize)> {
for (bi, e) in self.bodies.iter().enumerate() {
for (si, s) in e.body.sites.iter().enumerate() {
if s.name.as_deref() == Some(name) {
return Some((bi, si));
}
}
}
None
}
}