diff --git a/Cargo.toml b/Cargo.toml index 9a0877d..081fb35 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ glium = "*" image = "*" byteorder = "*" clap = "*" +nalgebra = "*" verbose-log = { git = "https://gitea.tforgione.fr/dash-3d/verbose-log" } [[bin]] diff --git a/src/camera.rs b/src/camera.rs index e620354..bca39c0 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -1,37 +1,24 @@ //! This module contains everything to deal with cameras. +use nalgebra::Matrix4; + use math::vector::Vector3; use math::frustum::Frustum; -/// Multiplies two matrices 4x4 -fn multiply_matrices(a: [[f32; 4]; 4], b: [[f32; 4]; 4]) -> [[f32; 4]; 4] { - let mut res = [[0.0; 4]; 4]; - - for i in 0..4 { - for j in 0..4 { - for k in 0..4 { - res[i][j] += a[i][k] + b[k][j]; - } - } - } - - res -} - /// The trait that a render camera should implement. /// /// It allows the renderer to use it. pub trait RenderCamera { /// Returns the view matrix of the camera. - fn get_view_matrix(&self) -> [[f32; 4]; 4]; + fn get_view_matrix(&self) -> Matrix4; /// Returns the perspective matrix of the camera. - fn get_perspective_matrix(&self) -> [[f32; 4]; 4]; + fn get_perspective_matrix(&self) -> Matrix4; /// Returns the product of the perspective matrix and the view matrix. - fn get_model_view_matrix(&self) -> [[f32; 4]; 4] { - multiply_matrices(self.get_perspective_matrix(), self.get_view_matrix()) + fn get_model_view_matrix(&self) -> Matrix4 { + self.get_perspective_matrix() * self.get_view_matrix().try_inverse().unwrap() } /// Returns the frustum of the camera. @@ -42,7 +29,7 @@ pub trait RenderCamera { } /// Creates a look at matrix from the center, the target pointed by the camera and the up vector. -pub fn look_at_matrix(position: [f32; 3], target: [f32; 3], up: [f32; 3]) -> [[f32; 4]; 4] { +pub fn look_at_matrix(position: [f32; 3], target: [f32; 3], up: [f32; 3]) -> Matrix4 { let f = { let f = [ target[0] - position[0], @@ -77,12 +64,12 @@ pub fn look_at_matrix(position: [f32; 3], target: [f32; 3], up: [f32; 3]) -> [[f [-s_norm[1], u[1], f[1], 0.0], [-s_norm[2], u[2], f[2], 0.0], [-p[0], p[1], p[2], 1.0], - ] + ].into() } /// Creates a perspective matrix of a camera. -pub fn perspective_matrix(aspect_ratio: f32, z_near: f32, z_far: f32) -> [[f32; 4]; 4] { +pub fn perspective_matrix(aspect_ratio: f32, z_near: f32, z_far: f32) -> Matrix4 { let fov = 3.141592 / 3.0; use num::Float; @@ -93,7 +80,7 @@ pub fn perspective_matrix(aspect_ratio: f32, z_near: f32, z_far: f32) -> [[f32; [ 0.0 , f , 0.0 , 0.0], [ 0.0 , 0.0, (z_far+z_near)/(z_far-z_near) , 1.0], [ 0.0 , 0.0, -(2.0*z_far*z_near)/(z_far-z_near), 0.0], - ] + ].into() } /// A simple camera with its position, target and up vector. @@ -139,11 +126,11 @@ impl Camera { } impl RenderCamera for Camera { - fn get_view_matrix(&self) -> [[f32; 4]; 4] { + fn get_view_matrix(&self) -> Matrix4 { look_at_matrix(self.position.into(), self.target.into(), self.up.into()) } - fn get_perspective_matrix(&self) -> [[f32; 4]; 4] { + fn get_perspective_matrix(&self) -> Matrix4 { perspective_matrix(self.aspect_ratio, self.z_near, self.z_far) } } diff --git a/src/lib.rs b/src/lib.rs index f682777..bf9b1af 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,6 +4,7 @@ extern crate num; extern crate image; +extern crate nalgebra; #[macro_use] extern crate verbose_log; #[macro_use] extern crate glium; diff --git a/src/math/frustum.rs b/src/math/frustum.rs index baafc42..be2a872 100644 --- a/src/math/frustum.rs +++ b/src/math/frustum.rs @@ -3,6 +3,8 @@ //! The frustum is the field of view of a camera. It allows you to make computation to know what is //! visible or not in an efficient manner, though it doesn't take occlusions into account. +use nalgebra::Matrix4; + use math::vector::Vector3; use math::plane::Plane; use math::bounding_box::BoundingBox3; @@ -18,12 +20,12 @@ impl Frustum { /// Creates a frustum from the matrix of a camera. /// /// This is *ahem...* slightly inspired from THREE.js Frustum - pub fn from_matrix(m: &[[f32; 4]; 4]) -> Frustum { + pub fn from_matrix(m: &Matrix4) -> Frustum { - let m0 = m[0][0]; let m1 = m[0][1]; let m2 = m[0][2]; let m3 = m[0][3]; - let m4 = m[1][0]; let m5 = m[1][1]; let m6 = m[1][2]; let m7 = m[1][3]; - let m8 = m[2][0]; let m9 = m[2][1]; let m10 = m[2][2]; let m11 = m[2][3]; - let m12 = m[3][0]; let m13 = m[3][1]; let m14 = m[3][2]; let m15 = m[3][3]; + let m0 = m[(0, 0)]; let m1 = m[(0, 1)]; let m2 = m[(0, 2)]; let m3 = m[(0, 3)]; + let m4 = m[(1, 0)]; let m5 = m[(1, 1)]; let m6 = m[(1, 2)]; let m7 = m[(1, 3)]; + let m8 = m[(2, 0)]; let m9 = m[(2, 1)]; let m10 = m[(2, 2)]; let m11 = m[(2, 3)]; + let m12 = m[(3, 0)]; let m13 = m[(3, 1)]; let m14 = m[(3, 2)]; let m15 = m[(3, 3)]; Frustum { planes: [ diff --git a/src/model/mod.rs b/src/model/mod.rs index 99a184e..2f279d7 100644 --- a/src/model/mod.rs +++ b/src/model/mod.rs @@ -285,6 +285,8 @@ impl Model { new_part.faces.push(face.clone()); new_faces.push(face); } + + new_part.needs_update = true; } for face in new_faces { diff --git a/src/renderer.rs b/src/renderer.rs index c02128c..548f937 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -156,9 +156,9 @@ impl Renderer { &self.program, &uniform!( tex: texture, - perspective: perspective, - view: view, - ), + perspective: Into::<[[f32; 4]; 4]>::into(perspective), + view: Into::<[[f32; 4]; 4]>::into(view), + ), ¶ms, ).unwrap(); }