use std::collections::HashMap;
use std::path::PathBuf;
use mjcf_rs::contact::{ContactExclude as MjcfContactExclude, ContactPair as MjcfContactPair};
use mjcf_rs::extras::{Actuator as MjcfActuator, Keyframe, Sensor as MjcfSensor};
use mjcf_rs::model::BodyId;
use rapier3d::dynamics::{GenericJoint, RigidBody};
use rapier3d::geometry::{Collider, SharedShape};
use rapier3d::math::{Pose, Real, Vector};
#[derive(Clone, Debug)]
pub struct MjcfBody {
pub name: Option<String>,
pub is_intermediate: bool,
pub mjcf_body_id: BodyId,
pub body: RigidBody,
pub colliders: Vec<Collider>,
pub gravcomp: f64,
pub mass: Real,
pub visual_meshes: Vec<MjcfVisualMesh>,
}
#[derive(Clone, Debug)]
pub struct MjcfVisualMesh {
pub shape: SharedShape,
pub local_pose: Pose,
pub rgba: Option<[f32; 4]>,
pub uvs: Option<Vec<[f32; 2]>>,
pub normals: Option<Vec<[f32; 3]>>,
pub texture: Option<PathBuf>,
pub material: Option<MjcfRenderMaterial>,
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct MjcfRenderMaterial {
pub metallic: f32,
pub roughness: f32,
pub reflectance: f32,
pub emissive: [f32; 3],
}
#[derive(Clone, Debug)]
pub struct MjcfJoint {
pub name: Option<String>,
pub link1: usize,
pub link2: usize,
pub joint: GenericJoint,
pub damping_per_dof: Real,
pub armature_per_dof: Real,
pub spring_stiffness_per_dof: Real,
pub spring_ref: Real,
pub springdamper: Option<(Real, Real)>,
}
#[derive(Clone, Debug)]
pub struct MjcfEqualityJoint {
pub name: Option<String>,
pub link1: usize,
pub link2: usize,
pub active: bool,
pub joint: GenericJoint,
}
#[derive(Copy, Clone, Debug)]
pub struct MjcfJointCoupling {
pub joint1: usize,
pub joint2: usize,
pub coeff: Real,
pub offset: Real,
pub active: bool,
}
#[derive(Clone, Debug)]
pub struct MjcfActuatorBinding {
pub actuator: MjcfActuator,
pub joint_index: Option<usize>,
}
#[derive(Clone, Debug)]
pub struct MjcfSensorBinding {
pub sensor: MjcfSensor,
pub object: SensorObjectRef,
}
#[derive(Clone, Debug, Default)]
pub enum SensorObjectRef {
#[default]
None,
Body(usize),
Joint(usize),
Site {
body: usize,
site: usize,
},
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum MjcfDofKind {
Free,
Ball,
Hinge,
Slide,
}
impl MjcfDofKind {
pub fn qpos_width(self) -> usize {
match self {
MjcfDofKind::Free => 7,
MjcfDofKind::Ball => 4,
MjcfDofKind::Hinge | MjcfDofKind::Slide => 1,
}
}
pub fn qvel_width(self) -> usize {
match self {
MjcfDofKind::Free => 6,
MjcfDofKind::Ball => 3,
MjcfDofKind::Hinge | MjcfDofKind::Slide => 1,
}
}
}
#[derive(Clone, Debug)]
pub struct MjcfQposDof {
pub kind: MjcfDofKind,
pub joint: Option<usize>,
pub body: usize,
pub reference: Real,
pub scale: Real,
}
#[derive(Clone, Debug, Default)]
pub struct MjcfRobot {
pub name: Option<String>,
pub bodies: Vec<MjcfBody>,
pub joints: Vec<MjcfJoint>,
pub equality_joints: Vec<MjcfEqualityJoint>,
pub joint_couplings: Vec<MjcfJointCoupling>,
pub actuators: Vec<MjcfActuatorBinding>,
pub sensors: Vec<MjcfSensorBinding>,
pub keyframes: Vec<Keyframe>,
pub qpos_dofs: Vec<MjcfQposDof>,
pub base_shift: Pose,
pub gravity: Vector,
pub body_name_to_idx: HashMap<String, usize>,
pub geom_name_to_collider: HashMap<String, (usize, usize)>,
pub joint_name_to_idx: HashMap<String, usize>,
pub contact_excludes: Vec<MjcfContactExclude>,
pub contact_pairs: Vec<MjcfContactPair>,
}