use std::str::FromStr; pub fn view_matrix(position: &[f32; 3], direction: &[f32; 3], up: &[f32; 3]) -> [[f32; 4]; 4] { let f = { let f = direction; let len = f[0] * f[0] + f[1] * f[1] + f[2] * f[2]; let len = len.sqrt(); [f[0] / len, f[1] / len, f[2] / len] }; let s = [up[1] * f[2] - up[2] * f[1], up[2] * f[0] - up[0] * f[2], up[0] * f[1] - up[1] * f[0]]; let s_norm = { let len = s[0] * s[0] + s[1] * s[1] + s[2] * s[2]; let len = len.sqrt(); [s[0] / len, s[1] / len, s[2] / len] }; let u = [f[1] * s_norm[2] - f[2] * s_norm[1], f[2] * s_norm[0] - f[0] * s_norm[2], f[0] * s_norm[1] - f[1] * s_norm[0]]; let p = [-position[0] * s_norm[0] - position[1] * s_norm[1] - position[2] * s_norm[2], -position[0] * u[0] - position[1] * u[1] - position[2] * u[2], -position[0] * f[0] - position[1] * f[1] - position[2] * f[2]]; [ [s[0], u[0], f[0], 0.0], [s[1], u[1], f[1], 0.0], [s[2], u[2], f[2], 0.0], [p[0], p[1], p[2], 1.0], ] } /// This little hacky function converts X-style args like "-root" to standard /// UNIX long-style args ("--root") that can be parsed by getopts. /// /// These variant long-form args should probably be hidden from the user, eg /// not show up in usage or manpage output. pub fn convert_xscreensaver_args(raw: Vec<&str>) -> Vec { let known_args = vec!["-root", "-window", "-mono", "-install", "-noinstall", "-visual", "-window-id", "-fps", "-no-fps", "-pair", "-record-animation"]; let ret: Vec = raw.into_iter().map(|arg| { if known_args.contains(&arg) { let mut longer = String::from_str("-").unwrap(); longer.push_str(arg); longer } else { String::from_str(arg).unwrap() } }).collect(); ret } #[test] fn test_xargconv() { assert_eq!(vec!["--root"], convert_xscreensaver_args(vec!["-root"])); assert_eq!(vec!["--root"], convert_xscreensaver_args(vec!["--root"])); assert_eq!(vec!["root"], convert_xscreensaver_args(vec!["root"])); assert_eq!(vec!["-asdf"], convert_xscreensaver_args(vec!["-asdf"])); assert_eq!(vec!["-h"], convert_xscreensaver_args(vec!["-h"])); }