diff --git a/nalgebra-glm/Cargo.toml b/nalgebra-glm/Cargo.toml index 02708ef1..aa072ade 100644 --- a/nalgebra-glm/Cargo.toml +++ b/nalgebra-glm/Cargo.toml @@ -12,6 +12,22 @@ categories = [ "science" ] keywords = [ "linear", "algebra", "matrix", "vector", "math" ] license = "BSD-3-Clause" +[features] + +default = ["opengl_projection"] + +opengl_projection = ["right_hand_default", "negone_to_one_clip_default"] +vulkan_projection = ["right_hand_default", "zero_to_one_clip_default", "projection_y_flip"] +directx_projection = ["left_hand_default", "zero_to_one_clip_default"] + +projection_y_flip = [] + +left_hand_default = [] +right_hand_default = [] + +zero_to_one_clip_default = [] +negone_to_one_clip_default = [] + [dependencies] num-traits = { version = "0.2", default-features = false } approx = { version = "0.3", default-features = false } diff --git a/nalgebra-glm/src/ext/matrix_clip_space.rs b/nalgebra-glm/src/ext/matrix_clip_space.rs index 89c137ea..6f9caa39 100644 --- a/nalgebra-glm/src/ext/matrix_clip_space.rs +++ b/nalgebra-glm/src/ext/matrix_clip_space.rs @@ -1,5 +1,5 @@ use aliases::TMat4; -use na::{Orthographic3, Perspective3, Real}; +use na::{Real}; //pub fn frustum(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4 { // unimplemented!() @@ -55,117 +55,969 @@ use na::{Orthographic3, Perspective3, Real}; /// Creates a matrix for an orthographic parallel viewing volume, using the right handedness and OpenGL near and far clip planes definition. pub fn ortho(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4 { - Orthographic3::new(left, right, bottom, top, znear, zfar).unwrap() + if cfg!(feature="zero_to_one_clip_default") { + ortho_zo(left, right, bottom, top, znear, zfar) + } else if cfg!(feature="negone_to_one_clip_default") { + ortho_no(left, right, bottom, top, znear, zfar) + } else { + unimplemented!() + } } -//pub fn ortho_lh(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4 { -// unimplemented!() -//} -// -//pub fn ortho_lh_no(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4 { -// unimplemented!() -//} -// -//pub fn ortho_lh_zo(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4 { -// unimplemented!() -//} -// -//pub fn ortho_no(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4 { -// unimplemented!() -//} -// -//pub fn ortho_rh(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4 { -// unimplemented!() -//} -// -//pub fn ortho_rh_no(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4 { -// unimplemented!() -//} -// -//pub fn ortho_rh_zo(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4 { -// unimplemented!() -//} -// -//pub fn ortho_zo(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4 { -// unimplemented!() -//} +pub fn ortho_lh(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4 { + if cfg!(feature="zero_to_one_clip_default") { + ortho_zo(left, right, bottom, top, znear, zfar) + } else if cfg!(feature="negone_to_one_clip_default") { + ortho_no(left, right, bottom, top, znear, zfar) + } else { + unimplemented!() + } +} -/// Creates a matrix for a perspective-view frustum based on the right handedness and OpenGL near and far clip planes definition. +pub fn ortho_lh_no(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4 { + let zero : N = ::convert(0.0); + let two : N = ::convert(2.0); + let mut mat : TMat4 = TMat4::::new(zero,zero,zero,zero, + zero,zero,zero,zero, + zero,zero,zero,zero, + zero,zero,zero,zero); + + let m11 = + if cfg!(feature="projection_y_flip") { + (two/(top-bottom)) * ::convert(-1.0) + } else { + (two/(top-bottom)) + }; + + mat[(0,0)] = two / (right - left); + mat[(1,1)] = m11; + mat[(2,2)] = two / (zfar - znear); + mat[(3,0)] = -(right + left) / (right - left); + mat[(3,1)] = -(top + bottom) / (top - bottom); + mat[(3,2)] = -(zfar + znear) / (zfar - znear); + + mat +} + +pub fn ortho_lh_zo(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4 { + let zero : N = ::convert(0.0); + let one : N = ::convert(1.0); + let two : N = ::convert(2.0); + let mut mat : TMat4 = TMat4::::new(zero,zero,zero,zero, + zero,zero,zero,zero, + zero,zero,zero,zero, + zero,zero,zero,zero); + + let m11 = + if cfg!(feature="projection_y_flip") { + (two/(top-bottom)) * ::convert(-1.0) + } else { + (two/(top-bottom)) + }; + + mat[(0,0)] = two / (right - left); + mat[(1,1)] = m11; + mat[(2,2)] = one / (zfar - znear); + mat[(3,0)] = - (right + left) / (right - left); + mat[(3,1)] = - (top + bottom) / (top - bottom); + mat[(3,2)] = - znear / (zfar - znear); + + mat +} + +pub fn ortho_no(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4 { + if cfg!(feature="left_hand_default") { + ortho_lh_no(left, right, bottom, top, znear, zfar) + } else if cfg!(feature="right_hand_default") { + ortho_rh_no(left, right, bottom, top, znear, zfar) + } else { + unimplemented!() + } +} + +pub fn ortho_rh(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4 { + if cfg!(feature="zero_to_one_clip_default") { + ortho_rh_zo(left, right, bottom, top, znear, zfar) + } else if cfg!(feature="negone_to_one_clip_default") { + ortho_rh_no(left, right, bottom, top, znear, zfar) + } else { + unimplemented!() + } +} + +pub fn ortho_rh_no(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4 { + let zero : N = ::convert(0.0); + let two : N = ::convert(2.0); + let mut mat : TMat4 = TMat4::::new(zero,zero,zero,zero, + zero,zero,zero,zero, + zero,zero,zero,zero, + zero,zero,zero,zero); + + let m11 = + if cfg!(feature="projection_y_flip") { + (two/(top-bottom)) * ::convert(-1.0) + } else { + (two/(top-bottom)) + }; + + mat[(0,0)] = two / (right - left); + mat[(1,1)] = m11; + mat[(2,2)] = - two / (zfar - znear); + mat[(3,0)] = - (right + left) / (right - left); + mat[(3,1)] = - (top + bottom) / (top - bottom); + mat[(3,2)] = - (zfar + znear) / (zfar - znear); + + mat +} + +pub fn ortho_rh_zo(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4 { + let zero : N = ::convert(0.0); + let one : N = ::convert(1.0); + let two : N = ::convert(2.0); + let mut mat : TMat4 = TMat4::::new(zero,zero,zero,zero, + zero,zero,zero,zero, + zero,zero,zero,zero, + zero,zero,zero,zero); + + let m11 = + if cfg!(feature="projection_y_flip") { + (two/(top-bottom)) * ::convert(-1.0) + } else { + (two/(top-bottom)) + }; + + mat[(0,0)] = two / (right - left); + mat[(1,1)] = m11; + mat[(2,2)] = - one / (zfar - znear); + mat[(3,0)] = - (right + left) / (right - left); + mat[(3,1)] = - (top + bottom) / (top - bottom); + mat[(3,2)] = - znear / (zfar - znear); + + mat +} + +pub fn ortho_zo(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4 { + if cfg!(feature="left_hand_default") { + ortho_lh_zo(left, right, bottom, top, znear, zfar) + } else if cfg!(feature="right_hand_default") { + ortho_rh_zo(left, right, bottom, top, znear, zfar) + } else { + unimplemented!() + } +} + +/// Creates a matrix for a perspective-view frustum with a handedness and depth range defined by the +/// defaults configured for the library at build time /// -/// # Important note -/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API. -pub fn perspective(aspect: N, fovy: N, near: N, far: N) -> TMat4 { - Perspective3::new(aspect, fovy, near, far).unwrap() +/// # Parameters +/// +/// * `fov` - Field of view, in radians +/// * `width` - Width of the viewport +/// * `height` - Height of the viewport +/// * `near` - Distance from the viewer to the near clipping plane +/// * `far` - Distance from the viewer to the far clipping plane +/// +/// # Compile Options +/// +/// There are 3 compile options that change the behaviour of the function: +/// 1. projection_y_flip +/// 2. left_hand_default/right_hand_default +/// 3. zero_to_one_clip_default/negone_to_one_clip_default +/// +/// ##### projection_y_flip +/// When enabled will perform a `matrix[(1,1)] *= 1` implicitly. Primary use case is for Vulkan +/// where the viewport coordinate origin is the top left, unlike OpenGL which is the bottom left. +/// +/// ##### left_hand_default/right_hand_default +/// Depending on which option is set the function will return either a left hand or a right +/// hand perspective matrix. +/// +/// ##### zero_to_one_clip_default/negone_to_one_clip_default +/// Depending on which option is set the function will return a perspective matrix meant for a +/// 0 to 1 depth clip space or a -1 to 1 depth clip space. +/// +pub fn perspective_fov(fov: N, width: N, height: N, near: N, far: N) -> TMat4 { + if cfg!(feature="zero_to_one_clip_default") { + perspective_fov_zo(fov, width, height, near, far) + } else if cfg!(feature="negone_to_one_clip_default") { + perspective_fov_no(fov, width, height, near, far) + } else { + unimplemented!() + } +} + +/// Creates a left handed matrix for a perspective-view frustum with a depth range defined by the +/// defaults configured for the library at build time +/// +/// # Parameters +/// +/// * `fov` - Field of view, in radians +/// * `width` - Width of the viewport +/// * `height` - Height of the viewport +/// * `near` - Distance from the viewer to the near clipping plane +/// * `far` - Distance from the viewer to the far clipping plane +/// +/// # Compile Options +/// +/// There are 2 compile options that change the behaviour of the function: +/// 1. projection_y_flip +/// 2. zero_to_one_clip_default/negone_to_one_clip_default +/// +/// ##### projection_y_flip +/// When enabled will perform a `matrix[(1,1)] *= 1` implicitly. Primary use case is for Vulkan +/// where the viewport coordinate origin is the top left, unlike OpenGL which is the bottom left. +/// +/// ##### zero_to_one_clip_default/negone_to_one_clip_default +/// Depending on which option is set the function will return a perspective matrix meant for a +/// 0 to 1 depth clip space or a -1 to 1 depth clip space. +/// +pub fn perspective_fov_lh(fov: N, width: N, height: N, near: N, far: N) -> TMat4 { + if cfg!(feature="zero_to_one_clip_default") { + perspective_fov_lh_zo(fov, width, height, near, far) + } else if cfg!(feature="negone_to_one_clip_default") { + perspective_fov_lh_no(fov, width, height, near, far) + } else { + unimplemented!() + } +} + +/// Creates a left hand matrix for a perspective-view frustum with a -1 to 1 depth range +/// +/// # Parameters +/// +/// * `fov` - Field of view, in radians +/// * `width` - Width of the viewport +/// * `height` - Height of the viewport +/// * `near` - Distance from the viewer to the near clipping plane +/// * `far` - Distance from the viewer to the far clipping plane +/// +/// # Compile Options +/// +/// There is 1 compile option that changes the behaviour of the function: +/// 1. projection_y_flip +/// +/// ##### projection_y_flip +/// When enabled will perform a `matrix[(1,1)] *= 1` implicitly. Primary use case is for Vulkan +/// where the viewport coordinate origin is the top left, unlike OpenGL which is the bottom left. +/// +pub fn perspective_fov_lh_no(fov: N, width: N, height: N, near: N, far: N) -> TMat4 { + assert!( + width > N::zero(), + "The width must be greater than zero" + ); + assert!( + height > N::zero(), + "The height must be greater than zero." + ); + assert!( + fov > N::zero(), + "The fov must be greater than zero" + ); + + let zero : N = ::convert( 0.0); + let mut mat : TMat4 = TMat4::::new(zero,zero,zero,zero, + zero,zero,zero,zero, + zero,zero,zero,zero, + zero,zero,zero,zero); + + let rad = fov; + let h = (rad * ::convert(0.5)).cos() / (rad * ::convert(0.5)).sin(); + let w = h * height / width; + + let m11 = + if cfg!(feature="projection_y_flip") { + h * ::convert(-1.0) + } else { + h + }; + + mat[(0,0)] = w; + mat[(1,1)] = m11; + mat[(2,2)] = (far + near) / (far - near); + mat[(2,3)] = ::convert(1.0); + mat[(3,2)] = - (far * near * ::convert(2.0)) / (far - near); + + mat +} + +/// Creates a left hand matrix for a perspective-view frustum with a 0 to 1 depth range +/// +/// # Parameters +/// +/// * `fov` - Field of view, in radians +/// * `width` - Width of the viewport +/// * `height` - Height of the viewport +/// * `near` - Distance from the viewer to the near clipping plane +/// * `far` - Distance from the viewer to the far clipping plane +/// +/// # Compile Options +/// +/// There is 1 compile option that changes the behaviour of the function: +/// 1. projection_y_flip +/// +/// ##### projection_y_flip +/// When enabled will perform a `matrix[(1,1)] *= 1` implicitly. Primary use case is for Vulkan +/// where the viewport coordinate origin is the top left, unlike OpenGL which is the bottom left. +/// +pub fn perspective_fov_lh_zo(fov: N, width: N, height: N, near: N, far: N) -> TMat4 { + assert!( + width > N::zero(), + "The width must be greater than zero" + ); + assert!( + height > N::zero(), + "The height must be greater than zero." + ); + assert!( + fov > N::zero(), + "The fov must be greater than zero" + ); + + let zero : N = ::convert( 0.0); + let mut mat : TMat4 = TMat4::::new(zero,zero,zero,zero, + zero,zero,zero,zero, + zero,zero,zero,zero, + zero,zero,zero,zero); + + let rad = fov; + let h = (rad * ::convert(0.5)).cos() / (rad * ::convert(0.5)).sin(); + let w = h * height / width; + + let m11 = + if cfg!(feature="projection_y_flip") { + h * ::convert(-1.0) + } else { + h + }; + + mat[(0,0)] = w; + mat[(1,1)] = m11; + mat[(2,2)] = far / (far - near); + mat[(2,3)] = ::convert(1.0); + mat[(3,2)] = -(far * near) / (far - near); + + mat +} + +/// Creates a matrix for a perspective-view frustum with a handedness defined by the defaults +/// configured for the library at build time and a depth range of -1 to 1 +/// +/// # Parameters +/// +/// * `fov` - Field of view, in radians +/// * `width` - Width of the viewport +/// * `height` - Height of the viewport +/// * `near` - Distance from the viewer to the near clipping plane +/// * `far` - Distance from the viewer to the far clipping plane +/// +/// # Compile Options +/// +/// There are 2 compile options that change the behaviour of the function: +/// 1. projection_y_flip +/// 2. left_hand_default/right_hand_default +/// +/// ##### projection_y_flip +/// When enabled will perform a `matrix[(1,1)] *= 1` implicitly. Primary use case is for Vulkan +/// where the viewport coordinate origin is the top left, unlike OpenGL which is the bottom left. +/// +/// ##### left_hand_default/right_hand_default +/// Depending on which option is set the function will return either a left hand or a right +/// hand perspective matrix. +/// +pub fn perspective_fov_no(fov: N, width: N, height: N, near: N, far: N) -> TMat4 { + if cfg!(feature="left_hand_default") { + perspective_fov_lh_no(fov, width, height, near, far) + } else if cfg!(feature="right_hand_default") { + perspective_fov_rh_no(fov, width, height, near, far) + } else { + unimplemented!() + } +} + +/// Creates a right handed matrix for a perspective-view frustum with a depth range defined by the +/// defaults configured for the library at build time +/// +/// # Parameters +/// +/// * `fov` - Field of view, in radians +/// * `width` - Width of the viewport +/// * `height` - Height of the viewport +/// * `near` - Distance from the viewer to the near clipping plane +/// * `far` - Distance from the viewer to the far clipping plane +/// +/// # Compile Options +/// +/// There are 2 compile options that change the behaviour of the function: +/// 1. projection_y_flip +/// 2. zero_to_one_clip_default/negone_to_one_clip_default +/// +/// ##### projection_y_flip +/// When enabled will perform a `matrix[(1,1)] *= 1` implicitly. Primary use case is for Vulkan +/// where the viewport coordinate origin is the top left, unlike OpenGL which is the bottom left. +/// +/// ##### zero_to_one_clip_default/negone_to_one_clip_default +/// Depending on which option is set the function will return a perspective matrix meant for a +/// 0 to 1 depth clip space or a -1 to 1 depth clip space. +/// +pub fn perspective_fov_rh(fov: N, width: N, height: N, near: N, far: N) -> TMat4 { + if cfg!(feature="zero_to_one_clip_default") { + perspective_fov_rh_zo(fov, width, height, near, far) + } else if cfg!(feature="negone_to_one_clip_default") { + perspective_fov_rh_no(fov, width, height, near, far) + } else { + unimplemented!() + } +} + +/// Creates a right hand matrix for a perspective-view frustum with a -1 to 1 depth range +/// +/// # Parameters +/// +/// * `fov` - Field of view, in radians +/// * `width` - Width of the viewport +/// * `height` - Height of the viewport +/// * `near` - Distance from the viewer to the near clipping plane +/// * `far` - Distance from the viewer to the far clipping plane +/// +/// # Compile Options +/// +/// There is 1 compile option that changes the behaviour of the function: +/// 1. projection_y_flip +/// +/// ##### projection_y_flip +/// When enabled will perform a `matrix[(1,1)] *= 1` implicitly. Primary use case is for Vulkan +/// where the viewport coordinate origin is the top left, unlike OpenGL which is the bottom left. +/// +pub fn perspective_fov_rh_no(fov: N, width: N, height: N, near: N, far: N) -> TMat4 { + assert!( + width > N::zero(), + "The width must be greater than zero" + ); + assert!( + height > N::zero(), + "The height must be greater than zero." + ); + assert!( + fov > N::zero(), + "The fov must be greater than zero" + ); + + let negone : N = ::convert(-1.0); + let zero : N = ::convert( 0.0); + let mut mat : TMat4 = TMat4::::new(zero,zero,zero,zero, + zero,zero,zero,zero, + zero,zero,zero,zero, + zero,zero,zero,zero); + + let rad = fov; + let h = (rad * ::convert(0.5)).cos() / (rad * ::convert(0.5)).sin(); + let w = h * height / width; + + let m11 = + if cfg!(feature="projection_y_flip") { + h * ::convert(-1.0) + } else { + h + }; + + mat[(0,0)] = w; + mat[(1,1)] = m11; + mat[(2,2)] = - (far + near) / (far - near); + mat[(2,3)] = negone; + mat[(3,2)] = - (far * near * ::convert(2.0)) / (far - near); + + mat +} + +/// Creates a right hand matrix for a perspective-view frustum with a 0 to 1 depth range +/// +/// # Parameters +/// +/// * `fov` - Field of view, in radians +/// * `width` - Width of the viewport +/// * `height` - Height of the viewport +/// * `near` - Distance from the viewer to the near clipping plane +/// * `far` - Distance from the viewer to the far clipping plane +/// +/// # Compile Options +/// +/// There is 1 compile option that changes the behaviour of the function: +/// 1. projection_y_flip +/// +/// ##### projection_y_flip +/// When enabled will perform a `matrix[(1,1)] *= 1` implicitly. Primary use case is for Vulkan +/// where the viewport coordinate origin is the top left, unlike OpenGL which is the bottom left. +/// +pub fn perspective_fov_rh_zo(fov: N, width: N, height: N, near: N, far: N) -> TMat4 { + assert!( + width > N::zero(), + "The width must be greater than zero" + ); + assert!( + height > N::zero(), + "The height must be greater than zero." + ); + assert!( + fov > N::zero(), + "The fov must be greater than zero" + ); + + let negone : N = ::convert(-1.0); + let zero : N = ::convert( 0.0); + let mut mat : TMat4 = TMat4::::new(zero,zero,zero,zero, + zero,zero,zero,zero, + zero,zero,zero,zero, + zero,zero,zero,zero); + + let rad = fov; + let h = (rad * ::convert(0.5)).cos() / (rad * ::convert(0.5)).sin(); + let w = h * height / width; + + let m11 = + if cfg!(feature="projection_y_flip") { + h * ::convert(-1.0) + } else { + h + }; + + mat[(0,0)] = w; + mat[(1,1)] = m11; + mat[(2,2)] = far / (near - far); + mat[(2,3)] = negone; + mat[(3,2)] = -(far * near) / (far - near); + + mat +} + +/// Creates a matrix for a perspective-view frustum with a handedness defined by the defaults +/// configured for the library at build time and a depth range of 0 to 1 +/// +/// # Parameters +/// +/// * `fov` - Field of view, in radians +/// * `width` - Width of the viewport +/// * `height` - Height of the viewport +/// * `near` - Distance from the viewer to the near clipping plane +/// * `far` - Distance from the viewer to the far clipping plane +/// +/// # Compile Options +/// +/// There are 2 compile options that change the behaviour of the function: +/// 1. projection_y_flip +/// 2. left_hand_default/right_hand_default +/// +/// ##### projection_y_flip +/// When enabled will perform a `matrix[(1,1)] *= 1` implicitly. Primary use case is for Vulkan +/// where the viewport coordinate origin is the top left, unlike OpenGL which is the bottom left. +/// +/// ##### left_hand_default/right_hand_default +/// Depending on which option is set the function will return either a left hand or a right +/// hand perspective matrix. +/// +pub fn perspective_fov_zo(fov: N, width: N, height: N, near: N, far: N) -> TMat4 { + if cfg!(feature="left_hand_default") { + perspective_fov_lh_zo(fov, width, height, near, far) + } else if cfg!(feature="right_hand_default") { + perspective_fov_rh_zo(fov, width, height, near, far) + } else { + unimplemented!() + } +} + +/// Creates a matrix for a perspective-view frustum with a handedness and depth range defined by the +/// defaults configured for the library at build time +/// +/// # Parameters +/// +/// * `fovy` - Field of view, in radians +/// * `aspect` - Ratio of viewport width to height (width/height) +/// * `near` - Distance from the viewer to the near clipping plane +/// * `far` - Distance from the viewer to the far clipping plane +/// +/// # Compile Options +/// +/// There are 3 compile options that change the behaviour of the function: +/// 1. projection_y_flip +/// 2. left_hand_default/right_hand_default +/// 3. zero_to_one_clip_default/negone_to_one_clip_default +/// +/// ##### projection_y_flip +/// When enabled will perform a `matrix[(1,1)] *= 1` implicitly. Primary use case is for Vulkan +/// where the viewport coordinate origin is the top left, unlike OpenGL which is the bottom left. +/// +/// ##### left_hand_default/right_hand_default +/// Depending on which option is set the function will return either a left hand or a right +/// hand perspective matrix. +/// +/// ##### zero_to_one_clip_default/negone_to_one_clip_default +/// Depending on which option is set the function will return a perspective matrix meant for a +/// 0 to 1 depth clip space or a -1 to 1 depth clip space. +/// +pub fn perspective(aspect: N, fovy: N, near: N, far: N) -> TMat4 { + // TODO: Breaking change: the arguments can be reversed back to proper glm conventions + if cfg!(feature="zero_to_one_clip_default") { + perspective_zo(aspect, fovy, near, far) + } else if cfg!(feature="negone_to_one_clip_default") { + perspective_no(aspect, fovy, near, far) + } else { + unimplemented!() + } +} + +/// Creates a left handed matrix for a perspective-view frustum with a depth range defined by the +/// defaults configured for the library at build time +/// +/// # Parameters +/// +/// * `fovy` - Field of view, in radians +/// * `aspect` - Ratio of viewport width to height (width/height) +/// * `near` - Distance from the viewer to the near clipping plane +/// * `far` - Distance from the viewer to the far clipping plane +/// +/// # Compile Options +/// +/// There are 2 compile options that change the behaviour of the function: +/// 1. projection_y_flip +/// 2. zero_to_one_clip_default/negone_to_one_clip_default +/// +/// ##### projection_y_flip +/// When enabled will perform a `matrix[(1,1)] *= 1` implicitly. Primary use case is for Vulkan +/// where the viewport coordinate origin is the top left, unlike OpenGL which is the bottom left. +/// +/// ##### zero_to_one_clip_default/negone_to_one_clip_default +/// Depending on which option is set the function will return a perspective matrix meant for a +/// 0 to 1 depth clip space or a -1 to 1 depth clip space. +/// +pub fn perspective_lh(aspect: N, fovy: N, near: N, far: N) -> TMat4 { + if cfg!(feature="zero_to_one_clip_default") { + perspective_lh_zo(fovy, aspect, near, far) + } else if cfg!(feature="negone_to_one_clip_default") { + perspective_lh_no(fovy, aspect, near, far) + } else { + unimplemented!() + } +} + +/// Creates a left hand matrix for a perspective-view frustum with a -1 to 1 depth range +/// +/// # Parameters +/// +/// * `fovy` - Field of view, in radians +/// * `aspect` - Ratio of viewport width to height (width/height) +/// * `near` - Distance from the viewer to the near clipping plane +/// * `far` - Distance from the viewer to the far clipping plane +/// +/// # Compile Options +/// +/// There is 1 compile option that changes the behaviour of the function: +/// 1. projection_y_flip +/// +/// ##### projection_y_flip +/// When enabled will perform a `matrix[(1,1)] *= 1` implicitly. Primary use case is for Vulkan +/// where the viewport coordinate origin is the top left, unlike OpenGL which is the bottom left. +/// +pub fn perspective_lh_no(aspect: N, fovy: N, near: N, far: N) -> TMat4 { + assert!( + !relative_eq!(far - near, N::zero()), + "The near-plane and far-plane must not be superimposed." + ); + assert!( + !relative_eq!(aspect, N::zero()), + "The apsect ratio must not be zero." + ); + + let zero : N = ::convert( 0.0); + let one : N = ::convert( 1.0); + let two : N = ::convert( 2.0); + let mut mat : TMat4 = TMat4::::new(zero,zero,zero,zero, + zero,zero,zero,zero, + zero,zero,zero,zero, + zero,zero,zero,zero); + + let tan_half_fovy = (fovy / two).tan(); + + let m11 = + if cfg!(feature="projection_y_flip") { + (one / tan_half_fovy) * ::convert(-1.0) + } else { + (one / tan_half_fovy) + }; + + mat[(0,0)] = one / (aspect * tan_half_fovy); + mat[(1,1)] = m11; + mat[(2,2)] = (far + near) / (far - near); + mat[(2,3)] = one; + mat[(3,2)] = -(two * far * near) / (far - near); + + mat +} + +/// Creates a left hand matrix for a perspective-view frustum with a 0 to 1 depth range +/// +/// # Parameters +/// +/// * `fovy` - Field of view, in radians +/// * `aspect` - Ratio of viewport width to height (width/height) +/// * `near` - Distance from the viewer to the near clipping plane +/// * `far` - Distance from the viewer to the far clipping plane +/// +/// # Compile Options +/// +/// There is 1 compile option that changes the behaviour of the function: +/// 1. projection_y_flip +/// +/// ##### projection_y_flip +/// When enabled will perform a `matrix[(1,1)] *= 1` implicitly. Primary use case is for Vulkan +/// where the viewport coordinate origin is the top left, unlike OpenGL which is the bottom left. +/// +pub fn perspective_lh_zo(aspect: N, fovy: N, near: N, far: N) -> TMat4 { + assert!( + !relative_eq!(far - near, N::zero()), + "The near-plane and far-plane must not be superimposed." + ); + assert!( + !relative_eq!(aspect, N::zero()), + "The apsect ratio must not be zero." + ); + + let zero : N = ::convert( 0.0); + let one : N = ::convert( 1.0); + let two : N = ::convert( 2.0); + let mut mat : TMat4 = TMat4::::new(zero,zero,zero,zero, + zero,zero,zero,zero, + zero,zero,zero,zero, + zero,zero,zero,zero); + + let tan_half_fovy = (fovy / two).tan(); + + let m11 = + if cfg!(feature="projection_y_flip") { + (one / tan_half_fovy) * ::convert(-1.0) + } else { + (one / tan_half_fovy) + }; + + mat[(0,0)] = one / (aspect * tan_half_fovy); + mat[(1,1)] = m11; + mat[(2,2)] = far / (far - near); + mat[(2,3)] = one; + mat[(3,2)] = -(far * near) / (far - near); + + mat +} + +/// Creates a matrix for a perspective-view frustum with a handedness defined by the defaults +/// configured for the library at build time and a depth range of -1 to 1 +/// +/// # Parameters +/// +/// * `fovy` - Field of view, in radians +/// * `aspect` - Ratio of viewport width to height (width/height) +/// * `near` - Distance from the viewer to the near clipping plane +/// * `far` - Distance from the viewer to the far clipping plane +/// +/// # Compile Options +/// +/// There are 2 compile options that change the behaviour of the function: +/// 1. projection_y_flip +/// 2. left_hand_default/right_hand_default +/// +/// ##### projection_y_flip +/// When enabled will perform a `matrix[(1,1)] *= 1` implicitly. Primary use case is for Vulkan +/// where the viewport coordinate origin is the top left, unlike OpenGL which is the bottom left. +/// +/// ##### left_hand_default/right_hand_default +/// Depending on which option is set the function will return either a left hand or a right +/// hand perspective matrix. +/// +pub fn perspective_no(aspect: N, fovy: N, near: N, far: N) -> TMat4 { + if cfg!(feature="left_hand_default") { + perspective_lh_no(aspect, fovy, near, far) + } else if cfg!(feature="right_hand_default") { + perspective_rh_no(aspect, fovy, near, far) + } else { + unimplemented!() + } +} + +/// Creates a right handed matrix for a perspective-view frustum with a depth range defined by the +/// defaults configured for the library at build time +/// +/// # Parameters +/// +/// * `fovy` - Field of view, in radians +/// * `aspect` - Ratio of viewport width to height (width/height) +/// * `near` - Distance from the viewer to the near clipping plane +/// * `far` - Distance from the viewer to the far clipping plane +/// +/// # Compile Options +/// +/// There are 2 compile options that change the behaviour of the function: +/// 1. projection_y_flip +/// 2. zero_to_one_clip_default/negone_to_one_clip_default +/// +/// ##### projection_y_flip +/// When enabled will perform a `matrix[(1,1)] *= 1` implicitly. Primary use case is for Vulkan +/// where the viewport coordinate origin is the top left, unlike OpenGL which is the bottom left. +/// +/// ##### zero_to_one_clip_default/negone_to_one_clip_default +/// Depending on which option is set the function will return a perspective matrix meant for a +/// 0 to 1 depth clip space or a -1 to 1 depth clip space. +/// +pub fn perspective_rh(aspect: N, fovy: N, near: N, far: N) -> TMat4 { + if cfg!(feature="zero_to_one_clip_default") { + perspective_rh_zo(aspect, fovy, near, far) + } else if cfg!(feature="negone_to_one_clip_default") { + perspective_rh_no(aspect, fovy, near, far) + } else { + unimplemented!() + } +} + +/// Creates a right hand matrix for a perspective-view frustum with a -1 to 1 depth range +/// +/// # Parameters +/// +/// * `fovy` - Field of view, in radians +/// * `aspect` - Ratio of viewport width to height (width/height) +/// * `near` - Distance from the viewer to the near clipping plane +/// * `far` - Distance from the viewer to the far clipping plane +/// +/// # Compile Options +/// +/// There is 1 compile option that changes the behaviour of the function: +/// 1. projection_y_flip +/// +/// ##### projection_y_flip +/// When enabled will perform a `matrix[(1,1)] *= 1` implicitly. Primary use case is for Vulkan +/// where the viewport coordinate origin is the top left, unlike OpenGL which is the bottom left. +/// +pub fn perspective_rh_no(aspect: N, fovy: N, near: N, far: N) -> TMat4 { + assert!( + !relative_eq!(far - near, N::zero()), + "The near-plane and far-plane must not be superimposed." + ); + assert!( + !relative_eq!(aspect, N::zero()), + "The apsect ratio must not be zero." + ); + + let negone : N = ::convert(-1.0); + let zero : N = ::convert( 0.0); + let one : N = ::convert( 1.0); + let two : N = ::convert( 2.0); + let mut mat : TMat4 = TMat4::::new(zero,zero,zero,zero, + zero,zero,zero,zero, + zero,zero,zero,zero, + zero,zero,zero,zero); + + let tan_half_fovy = (fovy / two).tan(); + + let m11 = + if cfg!(feature="projection_y_flip") { + (one / tan_half_fovy) * ::convert(-1.0) + } else { + (one / tan_half_fovy) + }; + + mat[(0,0)] = one / (aspect * tan_half_fovy); + mat[(1,1)] = m11; + mat[(2,2)] = - (far + near) / (far - near); + mat[(2,3)] = negone; + mat[(3,2)] = -(two * far * near) / (far - near); + + mat +} + +/// Creates a right hand matrix for a perspective-view frustum with a 0 to 1 depth range +/// +/// # Parameters +/// +/// * `fovy` - Field of view, in radians +/// * `aspect` - Ratio of viewport width to height (width/height) +/// * `near` - Distance from the viewer to the near clipping plane +/// * `far` - Distance from the viewer to the far clipping plane +/// +/// # Compile Options +/// +/// There is 1 compile option that changes the behaviour of the function: +/// 1. projection_y_flip +/// +/// ##### projection_y_flip +/// When enabled will perform a `matrix[(1,1)] *= 1` implicitly. Primary use case is for Vulkan +/// where the viewport coordinate origin is the top left, unlike OpenGL which is the bottom left. +/// +pub fn perspective_rh_zo(aspect: N, fovy: N, near: N, far: N) -> TMat4 { + assert!( + !relative_eq!(far - near, N::zero()), + "The near-plane and far-plane must not be superimposed." + ); + assert!( + !relative_eq!(aspect, N::zero()), + "The apsect ratio must not be zero." + ); + + let negone : N = ::convert(-1.0); + let zero : N = ::convert( 0.0); + let one : N = ::convert( 1.0); + let two : N = ::convert( 2.0); + let mut mat : TMat4 = TMat4::::new(zero,zero,zero,zero, + zero,zero,zero,zero, + zero,zero,zero,zero, + zero,zero,zero,zero); + + let tan_half_fovy = (fovy / two).tan(); + + let m11 = + if cfg!(feature="projection_y_flip") { + (one / tan_half_fovy) * ::convert(-1.0) + } else { + (one / tan_half_fovy) + }; + + mat[(0,0)] = one / (aspect * tan_half_fovy); + mat[(1,1)] = m11; + mat[(2,2)] = far / (near - far); + mat[(2,3)] = negone; + mat[(3,2)] = -(far * near) / (far - near); + + mat +} + +/// Creates a matrix for a perspective-view frustum with a handedness defined by the defaults +/// configured for the library at build time and a depth range of 0 to 1 +/// +/// # Parameters +/// +/// * `fovy` - Field of view, in radians +/// * `aspect` - Ratio of viewport width to height (width/height) +/// * `near` - Distance from the viewer to the near clipping plane +/// * `far` - Distance from the viewer to the far clipping plane +/// +/// # Compile Options +/// +/// There are 2 compile options that change the behaviour of the function: +/// 1. projection_y_flip +/// 2. left_hand_default/right_hand_default +/// +/// ##### projection_y_flip +/// When enabled will perform a `matrix[(1,1)] *= 1` implicitly. Primary use case is for Vulkan +/// where the viewport coordinate origin is the top left, unlike OpenGL which is the bottom left. +/// +/// ##### left_hand_default/right_hand_default +/// Depending on which option is set the function will return either a left hand or a right +/// hand perspective matrix. +/// +pub fn perspective_zo(aspect: N, fovy: N, near: N, far: N) -> TMat4 { + if cfg!(feature="left_hand_default") { + perspective_lh_zo(aspect, fovy, near, far) + } else if cfg!(feature="right_hand_default") { + perspective_rh_zo(aspect, fovy, near, far) + } else { + unimplemented!() + } } -//pub fn perspective_fov(fov: N, width: N, height: N, near: N, far: N) -> TMat4 { -// unimplemented!() -//} -// -//pub fn perspective_fov_lh(fov: N, width: N, height: N, near: N, far: N) -> TMat4 { -// unimplemented!() -//} -// -//pub fn perspective_fov_lh_no(fov: N, width: N, height: N, near: N, far: N) -> TMat4 { -// unimplemented!() -//} -// -//pub fn perspective_fov_lh_zo(fov: N, width: N, height: N, near: N, far: N) -> TMat4 { -// unimplemented!() -//} -// -//pub fn perspective_fov_no(fov: N, width: N, height: N, near: N, far: N) -> TMat4 { -// unimplemented!() -//} -// -//pub fn perspective_fov_rh(fov: N, width: N, height: N, near: N, far: N) -> TMat4 { -// unimplemented!() -//} -// -//pub fn perspective_fov_rh_no(fov: N, width: N, height: N, near: N, far: N) -> TMat4 { -// unimplemented!() -//} -// -//pub fn perspective_fov_rh_zo(fov: N, width: N, height: N, near: N, far: N) -> TMat4 { -// unimplemented!() -//} -// -//pub fn perspective_fov_zo(fov: N, width: N, height: N, near: N, far: N) -> TMat4 { -// unimplemented!() -//} -// -//pub fn perspective_lh(fovy: N, aspect: N, near: N, far: N) -> TMat4 { -// unimplemented!() -//} -// -//pub fn perspective_lh_no(fovy: N, aspect: N, near: N, far: N) -> TMat4 { -// unimplemented!() -//} -// -//pub fn perspective_lh_zo(fovy: N, aspect: N, near: N, far: N) -> TMat4 { -// unimplemented!() -//} -// -//pub fn perspective_no(fovy: N, aspect: N, near: N, far: N) -> TMat4 { -// unimplemented!() -//} -// -//pub fn perspective_rh(fovy: N, aspect: N, near: N, far: N) -> TMat4 { -// unimplemented!() -//} -// -//pub fn perspective_rh_no(fovy: N, aspect: N, near: N, far: N) -> TMat4 { -// unimplemented!() -//} -// -//pub fn perspective_rh_zo(fovy: N, aspect: N, near: N, far: N) -> TMat4 { -// unimplemented!() -//} -// -//pub fn perspective_zo(fovy: N, aspect: N, near: N, far: N) -> TMat4 { -// unimplemented!() -//} -// //pub fn tweaked_infinite_perspective(fovy: N, aspect: N, near: N) -> TMat4 { // unimplemented!() //} diff --git a/nalgebra-glm/src/ext/matrix_projection.rs b/nalgebra-glm/src/ext/matrix_projection.rs index d56103a6..4d6f090b 100644 --- a/nalgebra-glm/src/ext/matrix_projection.rs +++ b/nalgebra-glm/src/ext/matrix_projection.rs @@ -24,7 +24,8 @@ pub fn pick_matrix(center: &TVec2, delta: &TVec2, viewport: &TVec )) } -/// Map the specified object coordinates `(obj.x, obj.y, obj.z)` into window coordinates using OpenGL near and far clip planes definition. +/// Map the specified object coordinates `(obj.x, obj.y, obj.z)` into window coordinates using +/// the default configured depth range /// /// # Parameters: /// @@ -33,6 +34,15 @@ pub fn pick_matrix(center: &TVec2, delta: &TVec2, viewport: &TVec /// * `proj` - Specifies the current projection matrix. /// * `viewport` - Specifies the current viewport. /// +/// # Compile Options +/// +/// There are 2 compile options that change the behaviour of the function: +/// 1. zero_to_one_clip_default/negone_to_one_clip_default +/// +/// ##### zero_to_one_clip_default/negone_to_one_clip_default +/// Depending on which option is set the function will return a point un-projected with the depth +/// range of either 0 to 1 or -1 to 1 +/// /// # See also: /// /// * [`project_no`](fn.project_no.html) @@ -47,7 +57,13 @@ pub fn project( viewport: TVec4, ) -> TVec3 { - project_no(obj, model, proj, viewport) + if cfg!(feature="negone_to_one_clip_default") { + project_no(obj, model, proj, viewport) + } else if cfg!(feature="zero_to_one_clip_default") { + project_zo(obj, model, proj, viewport) + } else { + unimplemented!() + } } /// Map the specified object coordinates (obj.x, obj.y, obj.z) into window coordinates. @@ -114,7 +130,8 @@ pub fn project_zo( ) } -/// Map the specified window coordinates (win.x, win.y, win.z) into object coordinates using OpenGL near and far clip planes definition. +/// Map the specified window coordinates (win.x, win.y, win.z) into object coordinates using the +/// default configured depth range /// /// # Parameters: /// @@ -123,6 +140,15 @@ pub fn project_zo( /// * `proj` - Specifies the current projection matrix. /// * `viewport` - Specifies the current viewport. /// +/// # Compile Options +/// +/// There are 2 compile options that change the behaviour of the function: +/// 1. zero_to_one_clip_default/negone_to_one_clip_default +/// +/// ##### zero_to_one_clip_default/negone_to_one_clip_default +/// Depending on which option is set the function will return a point un-projected with the depth +/// range of either 0 to 1 or -1 to 1 +/// /// # See also: /// /// * [`project`](fn.project.html) @@ -137,7 +163,13 @@ pub fn unproject( viewport: TVec4, ) -> TVec3 { - unproject_no(win, model, proj, viewport) + if cfg!(feature="negone_to_one_clip_default") { + unproject_no(win, model, proj, viewport) + } else if cfg!(feature="zero_to_one_clip_default") { + unproject_zo(win, model, proj, viewport) + } else { + unimplemented!() + } } /// Map the specified window coordinates (win.x, win.y, win.z) into object coordinates. diff --git a/nalgebra-glm/src/ext/matrix_transform.rs b/nalgebra-glm/src/ext/matrix_transform.rs index 82926249..04fba4f7 100644 --- a/nalgebra-glm/src/ext/matrix_transform.rs +++ b/nalgebra-glm/src/ext/matrix_transform.rs @@ -9,6 +9,8 @@ where DefaultAllocator: Alloc { TMat::::identity() } +/// Build a look at view matrix with a handedness based on the defaults configured for the library +/// at compile time. /// Build a look at view matrix based on the right handedness. /// /// # Parameters: @@ -17,12 +19,27 @@ where DefaultAllocator: Alloc { /// * `center` − Position where the camera is looking at. /// * `u` − Normalized up vector, how the camera is oriented. Typically `(0, 1, 0)`. /// +/// # Compile Options +/// +/// There is 1 compile option that changes the behaviour of the function: +/// 1. left_hand_default/right_hand_default +/// +/// #### left_hand_default/right_hand_default +/// Depending on which option is set the function will return either a left hand or a right +/// hand matrix. It switches between using look_at_lh and look_at_rh. +/// /// # See also: /// /// * [`look_at_lh`](fn.look_at_lh.html) /// * [`look_at_rh`](fn.look_at_rh.html) pub fn look_at(eye: &TVec3, center: &TVec3, up: &TVec3) -> TMat4 { - look_at_rh(eye, center, up) + if cfg!(feature="right_hand_default") { + look_at_rh(eye, center, up) + } else if cfg!(feature="left_hand_default") { + look_at_lh(eye, center, up) + } else { + unimplemented!() + } } /// Build a left handed look at view matrix. diff --git a/nalgebra-glm/src/ext/mod.rs b/nalgebra-glm/src/ext/mod.rs index 6ad74ff6..0f9879ef 100644 --- a/nalgebra-glm/src/ext/mod.rs +++ b/nalgebra-glm/src/ext/mod.rs @@ -1,6 +1,16 @@ //! (Reexported) Additional features not specified by GLSL specification -pub use self::matrix_clip_space::{ortho, perspective}; +pub use self::matrix_clip_space::{ + ortho, ortho_lh, ortho_lh_no, ortho_lh_zo, ortho_no, ortho_rh, ortho_rh_no, ortho_rh_zo, + ortho_zo, + + perspective, perspective_lh, perspective_lh_no, perspective_lh_zo, perspective_no, + perspective_rh, perspective_rh_no, perspective_rh_zo, perspective_zo, + + perspective_fov, perspective_fov_lh,perspective_fov_lh_no, perspective_fov_lh_zo, + perspective_fov_no, perspective_fov_rh, perspective_fov_rh_no, perspective_fov_rh_zo, + perspective_fov_zo, +}; pub use self::matrix_projection::{ pick_matrix, project, project_no, project_zo, unproject, unproject_no, unproject_zo, }; diff --git a/nalgebra-glm/src/gtc/quaternion.rs b/nalgebra-glm/src/gtc/quaternion.rs index fd3e22bf..051ac360 100644 --- a/nalgebra-glm/src/gtc/quaternion.rs +++ b/nalgebra-glm/src/gtc/quaternion.rs @@ -5,7 +5,7 @@ use aliases::{Qua, TMat4, TVec, TVec3}; /// Euler angles of the quaternion `q` as (pitch, yaw, roll). pub fn quat_euler_angles(x: &Qua) -> TVec3 { let q = UnitQuaternion::new_unchecked(*x); - let a = q.to_euler_angles(); + let a = q.euler_angles(); TVec3::new(a.2, a.1, a.0) } @@ -34,9 +34,30 @@ pub fn quat_cast(x: &Qua) -> TMat4 { ::quat_to_mat4(x) } -/// Computes a right-handed look-at quaternion (equivalent to a right-handed look-at matrix). +/// Computes a look-at quaternion based on the defaults configured for the library at build time +/// +/// # Parameters +/// +/// * `direction` - Direction vector point at where to look +/// * `up` - Object up vector +/// +/// # Compile Options +/// +/// There is 1 compile option that changes the behaviour of the function: +/// 1. left_hand_default/right_hand_default +/// +/// ##### left_hand_default/right_hand_default +/// Depending on which option is set the function will return either a left hand or a right +/// hand look at quaternion. +/// pub fn quat_look_at(direction: &TVec3, up: &TVec3) -> Qua { - quat_look_at_rh(direction, up) + if cfg!(feature="right_hand_default") { + quat_look_at_rh(direction, up) + } else if cfg!(feature="left_hand_default") { + quat_look_at_lh(direction, up) + } else { + unimplemented!() + } } /// Computes a left-handed look-at quaternion (equivalent to a left-handed look-at matrix). diff --git a/nalgebra-glm/src/lib.rs b/nalgebra-glm/src/lib.rs index 85783014..71ffc251 100644 --- a/nalgebra-glm/src/lib.rs +++ b/nalgebra-glm/src/lib.rs @@ -142,12 +142,17 @@ pub use ext::{ epsilon, equal_columns, equal_columns_eps, equal_columns_eps_vec, equal_eps, equal_eps_vec, identity, look_at, look_at_lh, look_at_rh, max, max2, max3, max3_scalar, max4, max4_scalar, min, min2, min3, min3_scalar, min4, min4_scalar, not_equal_columns, not_equal_columns_eps, - not_equal_columns_eps_vec, not_equal_eps, not_equal_eps_vec, ortho, perspective, pi, - pick_matrix, project, project_no, project_zo, quat_angle, quat_angle_axis, quat_axis, - quat_conjugate, quat_cross, quat_dot, quat_equal, quat_equal_eps, quat_exp, quat_inverse, - quat_length, quat_lerp, quat_log, quat_magnitude, quat_normalize, quat_not_equal, - quat_not_equal_eps, quat_pow, quat_rotate, quat_slerp, rotate, rotate_x, rotate_y, rotate_z, - scale, translate, unproject, unproject_no, unproject_zo, + not_equal_columns_eps_vec, not_equal_eps, not_equal_eps_vec, ortho, perspective, perspective_fov, + perspective_fov_lh,perspective_fov_lh_no, perspective_fov_lh_zo, perspective_fov_no, + perspective_fov_rh, perspective_fov_rh_no, perspective_fov_rh_zo, perspective_fov_zo, + perspective_lh, perspective_lh_no, perspective_lh_zo, perspective_no, perspective_rh, + perspective_rh_no, perspective_rh_zo, perspective_zo, ortho_lh, ortho_lh_no, ortho_lh_zo, + ortho_no, ortho_rh, ortho_rh_no, ortho_rh_zo, ortho_zo, pi, pick_matrix, project, project_no, + project_zo, quat_angle, quat_angle_axis, quat_axis, quat_conjugate, quat_cross, quat_dot, + quat_equal, quat_equal_eps, quat_exp, quat_inverse, quat_length, quat_lerp, quat_log, + quat_magnitude, quat_normalize, quat_not_equal, quat_not_equal_eps, quat_pow, quat_rotate, + quat_slerp, rotate, rotate_x, rotate_y, rotate_z, scale, translate, unproject, unproject_no, + unproject_zo, }; pub use gtc::{ affine_inverse, column, e, euler, four_over_pi, golden_ratio, half_pi, inverse_transpose,