use crate::ode::*;
impl dSurfaceParameters {
pub fn new() -> dSurfaceParameters {
dSurfaceParameters{
mode: 0, mu: 0.0, mu2: 0.0, rho: 0.0, rho2: 0.0, rhoN: 0.0, bounce: 0.0, bounce_vel: 0.0, soft_erp: 0.0, soft_cfm: 0.0, motion1: 0.0, motion2: 0.0, motionN: 0.0, slip1: 0.0, slip2: 0.0} }
}
impl dContactGeom {
pub fn new() -> dContactGeom {
dContactGeom{
pos: [0.0; 4], normal: [0.0; 4], depth: 0.0, g1: 0 as dGeomID,
g2: 0 as dGeomID,
side1: 0, side2: 0} }
}
impl dContact {
pub fn new() -> dContact {
dContact{
surface: dSurfaceParameters::new(),
geom: dContactGeom::new(),
fdir1: [0.0; 4]} }
}
pub use std::f64::consts::PI;
pub static PId: dReal = PI * 2.0;
pub static PIh: dReal = PI / 2.0;
pub static PIt: dReal = PI / 3.0;
pub static PIq: dReal = PI / 4.0;
pub static PIx: dReal = PI / 6.0;
pub static PIh3: dReal = PIh * 3.0;
pub static PIt2: dReal = PIt * 2.0;
pub static PIt4: dReal = PIt * 4.0;
pub static PIt5: dReal = PIt * 5.0;
pub static PIq3: dReal = PIq * 3.0;
pub static PIx5: dReal = PIx * 5.0;
pub static M4I: dMatrix4 = [
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0];
pub static M3I: dMatrix3 = [
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0];
pub static QI: dQuaternion = [1.0, 0.0, 0.0, 0.0];
pub trait Quaternion {
fn as_ptr_mut(&mut self) -> *mut dReal;
fn as_ptr(&self) -> *const dReal;
fn new() -> dQuaternion {
let mut q: dQuaternion = [0.0; 4];
unsafe {
dQSetIdentity(q.as_ptr_mut());
}
q
}
fn from_R(m: dMatrix3) -> dQuaternion {
let mut q: dQuaternion = [0.0; 4];
unsafe {
dQfromR(q.as_ptr_mut(), m.as_ptr() as *mut dReal);
}
q
}
fn to_R(&self) -> dMatrix3 {
let mut m: dMatrix3 = [0.0; 12];
unsafe {
dRfromQ(m.as_ptr_mut(), self.as_ptr() as *mut dReal);
}
m
}
fn from_axis_and_angle(axis: [dReal; 3], angle: dReal) -> dQuaternion {
let mut q: dQuaternion = [0.0; 4];
unsafe {
dQFromAxisAndAngle(q.as_ptr_mut(), axis[0], axis[1], axis[2], angle);
}
q
}
fn multiply0(p: dQuaternion, q: dQuaternion) -> dQuaternion {
dQuaternion::multiply0_pp(p.as_ptr(), q.as_ptr())
}
fn multiply0_pp(p: *const dReal, q: *const dReal) -> dQuaternion {
let mut o: dQuaternion = [0.0; 4];
unsafe {
dQMultiply0(o.as_ptr_mut(), p as *mut dReal, q as *mut dReal);
}
o
}
fn multiply0_331(m: dMatrix3, v: dVector3) -> dVector3 {
dVector3::multiply0_331_pp(m.as_ptr(), v.as_ptr())
}
fn multiply0_331_pp(m: *const dReal, v: *const dReal) -> dVector3 {
let mut o: dVector3 = [0.0; 4];
unsafe {
dMULTIPLY0_331(o.as_ptr_mut(), m, v);
}
o
}
fn multiply0_441(m: dMatrix4, v: dVector4) -> dVector4 {
dVector4::multiply0_441_pp(m.as_ptr(), v.as_ptr())
}
fn multiply0_441_pp(m: *const dReal, v: *const dReal) -> dVector4 {
let mut o: dVector4 = [0.0; 4];
unsafe {
dMULTIPLY0_441(o.as_ptr_mut(), m, v);
}
o
}
fn conjugate(q: dQuaternion) -> dQuaternion {
dQuaternion::conjugate_ptr(q.as_ptr())
}
fn conjugate_ptr(q: *const dReal) -> dQuaternion {
unsafe {
let q = std::slice::from_raw_parts(q, 4);
[q[0], -q[1], -q[2], -q[3]]
}
}
fn prec_eq(&self, e: dReal, q: dQuaternion) -> bool;
fn as_vec(&self) -> ODEMat;
}
impl Quaternion for dQuaternion {
fn as_ptr_mut(&mut self) -> *mut dReal { &mut (*self)[0] as *mut dReal }
fn as_ptr(&self) -> *const dReal { &(*self)[0] as *const dReal }
fn prec_eq(&self, e: dReal, q: dQuaternion) -> bool {
for i in 0..4 {
if (self[i] - q[i]).abs() >= e { return false; }
}
true
}
fn as_vec(&self) -> ODEMat {
ODEMat::from_Q(self.as_ptr())
}
}
pub trait Matrix3 {
fn as_ptr_mut(&mut self) -> *mut dReal;
fn as_ptr(&self) -> *const dReal;
fn new() -> dMatrix3 {
let mut m: dMatrix3 = [0.0; 12];
unsafe {
dRSetIdentity(m.as_ptr_mut());
}
m
}
fn t(m: dMatrix3) -> dMatrix3 {
dMatrix3::t_ptr(m.as_ptr())
}
fn t_ptr(m: *const dReal) -> dMatrix3 {
unsafe {
let m = std::slice::from_raw_parts(m, 12);
[m[0], m[4], m[8], m[3],
m[1], m[5], m[9], m[7],
m[2], m[6], m[10], m[11]]
}
}
fn from_Q(q: dQuaternion) -> dMatrix3 {
let mut m: dMatrix3 = [0.0; 12];
unsafe {
dRfromQ(m.as_ptr_mut(), q.as_ptr() as *mut dReal);
}
m
}
fn to_Q(&self) -> dQuaternion {
let mut q: dQuaternion = [0.0; 4];
unsafe {
dQfromR(q.as_ptr_mut(), self.as_ptr() as *mut dReal);
}
q
}
fn from_axis_and_angle(axis: [dReal; 3], angle: dReal) -> dMatrix3 {
let mut m: dMatrix3 = [0.0; 12];
unsafe {
dRFromAxisAndAngle(m.as_ptr_mut(), axis[0], axis[1], axis[2], angle);
}
m
}
fn from_euler_angles(phi: dReal, theta: dReal, psi: dReal) -> dMatrix3 {
let mut m: dMatrix3 = [0.0; 12];
unsafe {
dRFromEulerAngles(m.as_ptr_mut(), phi, theta, psi);
}
m
}
fn from_2_axes(e0: [dReal; 3], e1: [dReal; 3]) -> dMatrix3 {
let mut m: dMatrix3 = [0.0; 12];
unsafe {
dRFrom2Axes(m.as_ptr_mut(), e0[0], e0[1], e0[2], e1[0], e1[1], e1[2]);
}
m
}
fn from_z_axis(e: [dReal; 3]) -> dMatrix3 {
let mut m: dMatrix3 = [0.0; 12];
unsafe {
dRFromZAxis(m.as_ptr_mut(), e[0], e[1], e[2]);
}
m
}
fn multiply0_333(a: dMatrix3, b: dMatrix3) -> dMatrix3 {
dMatrix3::multiply0_333_pp(a.as_ptr(), b.as_ptr())
}
fn multiply0_333_pp(a: *const dReal, b: *const dReal) -> dMatrix3 {
let mut m: dMatrix3 = [0.0; 12];
unsafe {
dMULTIPLY0_333(m.as_ptr_mut(), a, b);
}
m
}
fn prec_eq(&self, e: dReal, m: dMatrix3) -> bool;
fn as_mat(&self) -> ODEMat;
}
impl Matrix3 for dMatrix3 {
fn as_ptr_mut(&mut self) -> *mut dReal { &mut (*self)[0] as *mut dReal }
fn as_ptr(&self) -> *const dReal { &(*self)[0] as *const dReal }
fn prec_eq(&self, e: dReal, m: dMatrix3) -> bool {
for i in 0..12 {
if (self[i] - m[i]).abs() >= e { return false; }
}
true
}
fn as_mat(&self) -> ODEMat {
ODEMat::from_Mat3(self.as_ptr())
}
}
pub trait Matrix4 {
fn as_ptr_mut(&mut self) -> *mut dReal;
fn as_ptr(&self) -> *const dReal;
fn new() -> dMatrix4 {
let mut m: dMatrix4 = [0.0; 16];
for i in 0..4 { m[i * 5] = 1.0; }
m
}
fn t(m: dMatrix4) -> dMatrix4 {
dMatrix4::t_ptr(m.as_ptr())
}
fn t_ptr(m: *const dReal) -> dMatrix4 {
unsafe {
let m = std::slice::from_raw_parts(m, 16);
[m[0], m[4], m[8], m[12],
m[1], m[5], m[9], m[13],
m[2], m[6], m[10], m[14],
m[3], m[7], m[11], m[15]]
}
}
fn q_conjugate(m: dMatrix4) -> dMatrix4 {
dMatrix4::q_conjugate_ptr(m.as_ptr())
}
fn q_conjugate_ptr(m: *const dReal) -> dMatrix4 {
unsafe {
let m = std::slice::from_raw_parts(m, 16);
[m[0], -m[1], -m[2], -m[3],
-m[4], m[5], -m[6], -m[7],
-m[8], -m[9], m[10], -m[11],
-m[12], -m[13], -m[14], m[15]]
}
}
fn from_Conjugate_Q(q: dQuaternion) -> dMatrix4 {
dMatrix4::from_Q(dQuaternion::conjugate(q))
}
fn from_Conjugate_Q_ptr(q: *const dReal) -> dMatrix4 {
dMatrix4::from_Q(dQuaternion::conjugate_ptr(q))
}
fn from_P(p: dQuaternion) -> dMatrix4 {
dMatrix4::from_P_ptr(p.as_ptr())
}
fn from_P_ptr(p: *const dReal) -> dMatrix4 {
unsafe {
let p = std::slice::from_raw_parts(p, 4);
[ p[0], -p[1], -p[2], -p[3],
p[1], p[0], p[3], -p[2],
p[2], -p[3], p[0], p[1],
p[3], p[2], -p[1], p[0]]
}
}
fn from_Q(q: dQuaternion) -> dMatrix4 {
dMatrix4::from_Q_ptr(q.as_ptr())
}
fn from_Q_ptr(q: *const dReal) -> dMatrix4 {
unsafe {
let q = std::slice::from_raw_parts(q, 4);
[ q[0], -q[1], -q[2], -q[3],
q[1], q[0], -q[3], q[2],
q[2], q[3], q[0], -q[1],
q[3], -q[2], q[1], q[0]]
}
}
fn multiply0_444(a: dMatrix4, b: dMatrix4) -> dMatrix4 {
dMatrix4::multiply0_444_pp(a.as_ptr(), b.as_ptr())
}
fn multiply0_444_pp(a: *const dReal, b: *const dReal) -> dMatrix4 {
let mut m: dMatrix4 = [0.0; 16];
unsafe {
dMULTIPLY0_444(m.as_ptr_mut(), a, b);
}
m
}
fn is_quaternion(&self) -> bool;
fn to_Q(&self) -> dQuaternion;
fn prec_eq(&self, e: dReal, m: dMatrix4) -> bool;
fn as_mat(&self) -> ODEMat;
}
impl Matrix4 for dMatrix4 {
fn as_ptr_mut(&mut self) -> *mut dReal { &mut (*self)[0] as *mut dReal }
fn as_ptr(&self) -> *const dReal { &(*self)[0] as *const dReal }
fn is_quaternion(&self) -> bool {
if self[0] != self[5] || self[0] != self[10] || self[0] != self[15] {
return false;
}
if (self[4] != self[14] || self[8] != self[7] || self[12] != self[9])
&& (self[4] != self[11] || self[8] != self[13] || self[12] != self[6]) {
return false;
}
dMatrix4::t(dMatrix4::q_conjugate(*self)) == *self
}
fn to_Q(&self) -> dQuaternion {
if !self.is_quaternion() { panic!("not quaternion"); }
[self[0], self[4], self[8], self[12]]
}
fn prec_eq(&self, e: dReal, m: dMatrix4) -> bool {
for i in 0..16 {
if (self[i] - m[i]).abs() >= e { return false; }
}
true
}
fn as_mat(&self) -> ODEMat {
ODEMat::from_Mat4(self.as_ptr())
}
}
impl dMass {
pub fn new() -> dMass {
let mut mass: dMass = dMass{
mass: 0.0,
c: [0.0; 4], I: [0.0; 12]}; unsafe { dMassSetZero(&mut mass); } mass
}
}