Repository: bitshifter/glam-rs
Pull request #41 (2019-12-22 19:16:38)

 Added Mat4::orthographic_rh and Mat4::orthographic_lh.


Patch:
diff --git a/README.md b/README.md
index 25c54e6..293d009 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@ and the look and feel of the API has solidified.
 ## Features
 
 * Only single precision floating point (`f32`) arithmetic is supported
-* vectors: `Vec3`, `Vec3`, `Vec4`
+* vectors: `Vec2`, `Vec3`, `Vec4`
 * square matrices: `Mat2`, `Mat3`, `Mat4`
 * a quaternion type: `Quat`
 
diff --git a/src/f32/mat4.rs b/src/f32/mat4.rs
index ef74576..e141035 100644
--- a/src/f32/mat4.rs
+++ b/src/f32/mat4.rs
@@ -689,6 +689,56 @@ impl Mat4 {
         )
     }
 
+    /// Creates a left-handed orthographic projection matrix with [0,1] depth range.
+    pub fn orthographic_lh(
+        left: f32,
+        right: f32,
+        bottom: f32,
+        top: f32,
+        near: f32,
+        far: f32,
+    ) -> Self {
+        let rcp_width = 1.0 / (right - left);
+        let rcp_height = 1.0 / (top - bottom);
+        let r = 1.0 / (far - near);
+        Mat4::from_cols(
+            Vec4::new(rcp_width + rcp_width, 0.0, 0.0, 0.0),
+            Vec4::new(0.0, rcp_height + rcp_height, 0.0, 0.0),
+            Vec4::new(0.0, 0.0, r, 0.0),
+            Vec4::new(
+                -(left + right) * rcp_width,
+                -(top + bottom) * rcp_height,
+                -r * near,
+                1.0,
+            ),
+        )
+    }
+
+    /// Creates a right-handed orthographic projection matrix with [0,1] depth range.
+    pub fn orthographic_rh(
+        left: f32,
+        right: f32,
+        bottom: f32,
+        top: f32,
+        near: f32,
+        far: f32,
+    ) -> Self {
+        let rcp_width = 1.0 / (right - left);
+        let rcp_height = 1.0 / (top - bottom);
+        let r = 1.0 / (near - far);
+        Mat4::from_cols(
+            Vec4::new(rcp_width + rcp_width, 0.0, 0.0, 0.0),
+            Vec4::new(0.0, rcp_height + rcp_height, 0.0, 0.0),
+            Vec4::new(0.0, 0.0, r, 0.0),
+            Vec4::new(
+                -(left + right) * rcp_width,
+                -(top + bottom) * rcp_height,
+                r * near,
+                1.0,
+            ),
+        )
+    }
+
     #[inline]
     pub fn mul_vec4(&self, other: Vec4) -> Vec4 {
         let mut res = self.x_axis * other.dup_x();


Test patch:
diff --git a/tests/mat4.rs b/tests/mat4.rs
index 7cdcd46..3d8f34e 100644
--- a/tests/mat4.rs
+++ b/tests/mat4.rs
@@ -386,6 +386,30 @@ fn test_mat4_orthographic_gl_rh() {
     assert_approx_eq!(projected, Vec4::new(0.5, 1.0, -2.0, 1.0));
 }
 
+#[test]
+fn test_mat4_orthographic_rh() {
+    let projection = Mat4::orthographic_rh(-10.0, 10.0, -5.0, 5.0, -10.0, 10.0);
+    let original = Vec4::new(5.0, 5.0, -5.0, 1.0);
+    let projected = projection.mul_vec4(original);
+    assert_approx_eq!(projected, Vec4::new(0.5, 1.0, 0.75, 1.0));
+
+    let original = Vec4::new(5.0, 5.0, 5.0, 1.0);
+    let projected = projection.mul_vec4(original);
+    assert_approx_eq!(projected, Vec4::new(0.5, 1.0, 0.25, 1.0));
+}
+
+#[test]
+fn test_mat4_orthographic_lh() {
+    let projection = Mat4::orthographic_lh(-10.0, 10.0, -5.0, 5.0, -10.0, 10.0);
+    let original = Vec4::new(5.0, 5.0, -5.0, 1.0);
+    let projected = projection.mul_vec4(original);
+    assert_approx_eq!(projected, Vec4::new(0.5, 1.0, 0.25, 1.0));
+
+    let original = Vec4::new(5.0, 5.0, 5.0, 1.0);
+    let projected = projection.mul_vec4(original);
+    assert_approx_eq!(projected, Vec4::new(0.5, 1.0, 0.75, 1.0));
+}
+
 #[test]
 fn test_mat4_ops() {
     let m0 = Mat4::from_cols_array_2d(&MATRIX);