use crate::ode::*;
use crate::ode::mat::*;
use crate::ode::prim::*;
use crate::ode::meta::*;
fn fake_type_name_of_val<T>(_: &T) -> &'static str {
std::any::type_name::<T>()
}
enum ClsId {
World = 1, Space, Body, Geom, JointGroup
}
macro_rules! chk_src_type {
($n: expr, $obj: ident, $src: expr) => {{
let o = fake_type_name_of_val(&$obj); let t = fake_type_name_of_val(&$src);
let v = $src as usize;
let mut r = (None, v);
if &t[..5] == "*mut " { let p: Vec<_> = t.match_indices("::").collect(); if p.len() > 0 {
let s = &t[p[p.len() - 1].0+4..]; r = (match s {
"World" => { Some(ClsId::World) },
"Space" => { Some(ClsId::Space) },
"Body" => { Some(ClsId::Body) },
"Geom" => { Some(ClsId::Geom) },
"JointGroup" => { Some(ClsId::JointGroup) },
_ => { println!("unknown pattern of {} {}, {}", $n, o, t); None }
}, v)
}
}
r
}};
}
macro_rules! from_id {
(obg: $obj: ident, $src: expr) => {
let (k, v) = chk_src_type!("Obg", $obj, $src);
match k {
Some(ClsId::Body) => { $obj.body = v },
Some(ClsId::Geom) => { $obj.geom = v },
_ => {}
}
};
(gws: $obj: ident, $src: expr) => {
let (k, v) = chk_src_type!("Gws", $obj, $src);
match k {
Some(ClsId::World) => { $obj.world = v },
Some(ClsId::Space) => { $obj.space = v },
Some(ClsId::Geom) => { $obj.ground = v },
Some(ClsId::JointGroup) => { $obj.contactgroup = v },
_ => {}
}
};
($obj: ident, $src: expr, $dst: ident) => { $obj.$dst = $src as usize };
}
macro_rules! as_id { ($obj: ident, body) => { $obj.body as dBodyID };
($obj: ident, geom) => { $obj.geom as dGeomID };
($obj: ident, world) => { $obj.world as dWorldID };
($obj: ident, space) => { $obj.space as dSpaceID };
($obj: ident, ground) => { $obj.ground as dGeomID };
($obj: ident, contactgroup) => { $obj.contactgroup as dJointGroupID };
($obj: ident, $src: ident, $dst: ty) => { $obj.$src as $dst };
}
pub struct Obg { pub key: String,
body: usize, geom: usize, pub col: dVector4
}
impl Obg {
pub fn new(key: &str, body: dBodyID, geom: dGeomID, col: dVector4) -> Obg {
Obg{key: key.to_string(), body: body as usize, geom: geom as usize, col: col}
}
pub fn body_(&mut self, id: dBodyID) { from_id!(obg: self, id); }
pub fn body(&self) -> dBodyID { as_id!(self, body) }
pub fn geom_(&mut self, id: dGeomID) { from_id!(obg: self, id); }
pub fn geom(&self) -> dGeomID { as_id!(self, geom) }
pub fn get_mass_by_id(id: dBodyID, mass: &mut dMass) {
unsafe {
dBodyGetMass(id, mass as *mut dMass)
}
}
pub fn get_mass(&self, mass: &mut dMass) {
Obg::get_mass_by_id(self.body(), mass)
}
pub fn get_linear_vel_mut_by_id(id: dBodyID) -> dVector3 {
unsafe {
*(dBodyGetLinearVel(id) as *mut dVector3)
}
}
pub fn linear_vel_ptr_mut(&mut self) -> *mut [dReal; 4] {
unsafe {
let p: *mut dReal = dBodyGetLinearVel(self.body()) as *mut dReal;
p as *mut [dReal; 4]
}
}
pub fn linear_vel_(&mut self) -> &mut [dReal] {
unsafe {
std::slice::from_raw_parts_mut(self.linear_vel_ptr_mut() as *mut dReal, 4)
}
}
pub fn linear_vel(&self) -> &[dReal] {
unsafe {
let p: *const dReal = dBodyGetLinearVel(self.body());
std::slice::from_raw_parts(p, 4)
}
}
pub fn linear_vel_vec(&self) -> ODEMat {
ODEMat::as_vec(self.linear_vel())
}
pub fn get_angular_vel_mut_by_id(id: dBodyID) -> dVector3 {
unsafe {
*(dBodyGetAngularVel(id) as *mut dVector3)
}
}
pub fn angular_vel_ptr_mut(&mut self) -> *mut [dReal; 4] {
unsafe {
let p: *mut dReal = dBodyGetAngularVel(self.body()) as *mut dReal;
p as *mut [dReal; 4]
}
}
pub fn angular_vel_(&mut self) -> &mut [dReal] {
unsafe {
std::slice::from_raw_parts_mut(self.angular_vel_ptr_mut() as *mut dReal, 4)
}
}
pub fn angular_vel(&self) -> &[dReal] {
unsafe {
let p: *const dReal = dBodyGetAngularVel(self.body());
std::slice::from_raw_parts(p, 4)
}
}
pub fn angular_vel_vec(&self) -> ODEMat {
ODEMat::as_vec(self.angular_vel())
}
pub fn get_pos_mut_by_id(id: dBodyID) -> dVector3 {
unsafe {
*(dBodyGetPosition(id) as *mut dVector3)
}
}
pub fn pos_ptr_mut(&mut self) -> *mut [dReal; 4] {
unsafe {
let p: *mut dReal = dBodyGetPosition(self.body()) as *mut dReal;
p as *mut [dReal; 4]
}
}
pub fn pos_(&mut self) -> &mut [dReal] {
unsafe {
std::slice::from_raw_parts_mut(self.pos_ptr_mut() as *mut dReal, 4)
}
}
pub fn pos(&self) -> &[dReal] {
unsafe {
let p: *const dReal = dBodyGetPosition(self.body());
std::slice::from_raw_parts(p, 4)
}
}
pub fn pos_vec(&self) -> ODEMat {
ODEMat::as_vec(self.pos())
}
pub fn get_quaternion_mut_by_id(id: dBodyID) -> dVector4 {
unsafe {
*(dBodyGetQuaternion(id) as *mut dVector4)
}
}
pub fn quaternion_ptr_mut(&mut self) -> *mut [dReal; 4] {
unsafe {
let p: *mut dReal = dBodyGetQuaternion(self.body()) as *mut dReal;
p as *mut [dReal; 4]
}
}
pub fn quaternion_(&mut self) -> &mut [dReal] {
unsafe {
std::slice::from_raw_parts_mut(self.quaternion_ptr_mut() as *mut dReal, 4)
}
}
pub fn quaternion(&self) -> &[dReal] {
unsafe {
let p: *const dReal = dBodyGetQuaternion(self.body());
std::slice::from_raw_parts(p, 4)
}
}
pub fn quaternion_vec(&self) -> ODEMat {
ODEMat::as_vec(self.quaternion())
}
pub fn get_rot_mut_by_id(id: dBodyID) -> dMatrix3 {
unsafe {
*(dBodyGetRotation(id) as *mut dMatrix3)
}
}
pub fn rot_ptr_mut(&mut self) -> *mut [[dReal; 4]; 3] {
unsafe {
let p: *mut dReal = dBodyGetRotation(self.body()) as *mut dReal;
p as *mut [[dReal; 4]; 3]
}
}
pub fn rot_(&mut self) -> &mut [dReal] {
unsafe {
std::slice::from_raw_parts_mut(self.rot_ptr_mut() as *mut dReal, 12)
}
}
pub fn rot(&self) -> &[dReal] {
unsafe {
let p: *const dReal = dBodyGetRotation(self.body());
std::slice::from_raw_parts(p, 12)
}
}
pub fn rot_mat3(&self) -> ODEMat {
ODEMat::as_mat(3, self.rot())
}
pub fn set_mass_by_id(id: dBodyID, mass: &dMass) {
unsafe {
dBodySetMass(id, mass as *const dMass)
}
}
pub fn set_mass(&mut self, mass: &dMass) -> &mut Obg {
Obg::set_mass_by_id(self.body(), mass);
self
}
pub fn set_linear_vel_by_id(id: dBodyID, xyz: &dVector3) {
unsafe {
dBodySetLinearVel(id, xyz[0], xyz[1], xyz[2]);
}
}
pub fn set_linear_vel(&mut self, xyz: dVector3) -> &mut Obg {
Obg::set_linear_vel_by_id(self.body(), &xyz);
self
}
pub fn set_angular_vel_by_id(id: dBodyID, xyz: &dVector3) {
unsafe {
dBodySetAngularVel(id, xyz[0], xyz[1], xyz[2]);
}
}
pub fn set_angular_vel(&mut self, xyz: dVector3) -> &mut Obg {
Obg::set_angular_vel_by_id(self.body(), &xyz);
self
}
pub fn set_pos_by_id(id: dBodyID, pos: &dVector3) {
unsafe {
dBodySetPosition(id, pos[0], pos[1], pos[2]);
}
}
pub fn set_pos(&mut self, pos: dVector3) -> &mut Obg {
Obg::set_pos_by_id(self.body(), &pos);
self
}
pub fn set_quaternion_by_id(id: dBodyID, q: &dQuaternion) {
unsafe {
dBodySetQuaternion(id, q.as_ptr() as *mut dReal);
}
}
pub fn set_quaternion(&mut self, q: dQuaternion) -> &mut Obg {
Obg::set_quaternion_by_id(self.body(), &q);
self
}
pub fn set_rot_by_id(id: dBodyID, rot: &dMatrix3) {
unsafe {
dBodySetRotation(id, rot.as_ptr() as *mut dReal);
}
}
pub fn set_rot(&mut self, rot: dMatrix3) -> &mut Obg {
Obg::set_rot_by_id(self.body(), &rot);
self
}
pub fn set_torque_by_id(id: dBodyID, t: &[dReal; 3]) {
unsafe {
dBodySetTorque(id, t[0], t[1], t[2]);
}
}
pub fn set_torque(&mut self, t: [dReal; 3]) -> &mut Obg {
Obg::set_torque_by_id(self.body(), &t);
self
}
pub fn add_torque_by_id(id: dBodyID, t: &[dReal; 3]) {
unsafe {
dBodyAddTorque(id, t[0], t[1], t[2]);
}
}
pub fn add_torque(&mut self, t: [dReal; 3]) -> &mut Obg {
Obg::add_torque_by_id(self.body(), &t);
self
}
pub fn add_rel_torque_by_id(id: dBodyID, t: &[dReal; 3]) {
unsafe {
dBodyAddRelTorque(id, t[0], t[1], t[2]);
}
}
pub fn add_rel_torque(&mut self, t: [dReal; 3]) -> &mut Obg {
Obg::add_rel_torque_by_id(self.body(), &t);
self
}
pub fn set_force_by_id(id: dBodyID, f: &[dReal; 3]) {
unsafe {
dBodySetForce(id, f[0], f[1], f[2]);
}
}
pub fn set_force(&mut self, f: [dReal; 3]) -> &mut Obg {
Obg::set_force_by_id(self.body(), &f);
self
}
pub fn add_force_by_id(id: dBodyID, f: &[dReal; 3]) {
unsafe {
dBodyAddForce(id, f[0], f[1], f[2]);
}
}
pub fn add_force(&mut self, f: [dReal; 3]) -> &mut Obg {
Obg::add_force_by_id(self.body(), &f);
self
}
pub fn add_rel_force_by_id(id: dBodyID, f: &[dReal; 3]) {
unsafe {
dBodyAddRelForce(id, f[0], f[1], f[2]);
}
}
pub fn add_rel_force(&mut self, f: [dReal; 3]) -> &mut Obg {
Obg::add_rel_force_by_id(self.body(), &f);
self
}
pub fn add_force_at_by_id(id: dBodyID, f: &[dReal; 3], p: &[dReal; 3]) {
unsafe {
dBodyAddForceAtPos(id, f[0], f[1], f[2], p[0], p[1], p[2]);
}
}
pub fn add_force_at(&mut self, f: [dReal; 3], p: [dReal; 3]) -> &mut Obg {
Obg::add_force_at_by_id(self.body(), &f, &p);
self
}
pub fn add_rel_force_at_by_id(id: dBodyID, f: &[dReal; 3], p: &[dReal; 3]) {
unsafe {
dBodyAddRelForceAtPos(id, f[0], f[1], f[2], p[0], p[1], p[2]);
}
}
pub fn add_rel_force_at(&mut self, f: [dReal; 3], p: [dReal; 3]) -> &mut Obg {
Obg::add_rel_force_at_by_id(self.body(), &f, &p);
self
}
pub fn add_force_rel_by_id(id: dBodyID, f: &[dReal; 3], p: &[dReal; 3]) {
unsafe {
dBodyAddForceAtRelPos(id, f[0], f[1], f[2], p[0], p[1], p[2]);
}
}
pub fn add_force_rel(&mut self, f: [dReal; 3], p: [dReal; 3]) -> &mut Obg {
Obg::add_force_rel_by_id(self.body(), &f, &p);
self
}
pub fn add_rel_force_rel_by_id(id: dBodyID, f: &[dReal; 3], p: &[dReal; 3]) {
unsafe {
dBodyAddRelForceAtRelPos(id, f[0], f[1], f[2], p[0], p[1], p[2]);
}
}
pub fn add_rel_force_rel(&mut self, f: [dReal; 3], p: [dReal; 3]) -> &mut Obg {
Obg::add_rel_force_rel_by_id(self.body(), &f, &p);
self
}
pub fn is_enabled(&self) -> bool {
unsafe {
dBodyIsEnabled(self.body()) != 0
}
}
pub fn disable(&mut self) {
unsafe {
dBodyDisable(self.body());
}
}
pub fn enable(&mut self) {
unsafe {
dBodyEnable(self.body());
}
}
}
pub struct Gws { world: usize,
space: usize,
ground: usize,
contactgroup: usize,
num_contact: usize,
pub contacts: Vec<dContact>
}
impl Gws {
pub fn new(num_contact: usize) -> Gws {
let contacts = (0..num_contact).into_iter().map(|_|
dContact::new()
).collect::<Vec<_>>();
Gws{world: 0, space: 0, ground: 0, contactgroup: 0, num_contact, contacts}
}
pub fn world_(&mut self, id: dWorldID) { from_id!(gws: self, id); }
pub fn world(&self) -> dWorldID { as_id!(self, world) }
pub fn space_(&mut self, id: dSpaceID) { from_id!(gws: self, id); }
pub fn space(&self) -> dSpaceID { as_id!(self, space) }
pub fn ground_(&mut self, id: dGeomID) { from_id!(gws: self, id); }
pub fn ground(&self) -> dGeomID { as_id!(self, ground) }
pub fn contactgroup_(&mut self, id: dJointGroupID) { from_id!(gws: self, id); }
pub fn contactgroup(&self) -> dJointGroupID { as_id!(self, contactgroup) }
pub fn num_contact_(&mut self, nc: usize) { self.num_contact = nc; }
pub fn num_contact(&self) -> usize { self.num_contact }
}