e2rcore/implement/math/
util.rs

1extern crate mazth;
2
3use ::std::f32;
4
5use self::mazth::mat;
6
7pub fn perspective( fov: f32, aspect: f32, near: f32, far: f32 ) -> mat::Mat4< f32 > {
8    //fov is the full field of view in y-plane, eg: fovy = fov/2
9    let half_tan = (fov * f32::consts::PI / 360.0f32).tan();
10    //creates a frustum
11    let mut out : mat::Mat4<f32> = Default::default();
12    *out.index_mut(0, 0) = 1.0/(aspect*half_tan);
13    *out.index_mut(1, 1) = 1.0/half_tan;
14    *out.index_mut(2, 2) = (far+near)/(near-far);
15    *out.index_mut(3, 2) = -1f32;
16    *out.index_mut(2, 3) = (2.0f32*far*near)/(near-far);
17    out
18}
19
20pub fn look_at( eye: mat::Mat3x1< f32 >, center: mat::Mat3x1< f32 >, up: mat::Mat3x1< f32 > ) -> mat::Mat4< f32 > {
21
22    //compute viewing plane's normal vector
23    let mut n : mat::Mat3x1<f32> = Default::default();
24    for i in 0..3{
25	n[i] = eye[i] - center[i];
26    }
27    n = n.normalize().unwrap();
28
29    //compute 1 orthogonal vector to plane's normal vector
30    let up_vec = up.normalize().unwrap();
31    let u = up_vec.cross( &n ).unwrap().normalize().unwrap();
32    
33    //compute the other orthogonal vector to plane's normal vector
34    let v = n.cross( &u ).unwrap().normalize().unwrap();
35
36    //space_original = a_inverse * space_camera
37    //a is a rotation matrix, which means a_inverse = a_transpose
38    //a is finally augmented with translations on the last column
39    let mut camera_view : mat::Mat4<f32> = Default::default();
40    *camera_view.index_mut( 0, 0 ) = u[0];
41    *camera_view.index_mut( 0, 1 ) = u[1];
42    *camera_view.index_mut( 0, 2 ) = u[2];
43    *camera_view.index_mut( 0, 3 ) = -1f32 * (eye[0]*u[0] + eye[1]*u[1] + eye[2]*u[2]);
44    *camera_view.index_mut( 1, 0 ) = v[0];
45    *camera_view.index_mut( 1, 1 ) = v[1];
46    *camera_view.index_mut( 1, 2 ) = v[2];
47    *camera_view.index_mut( 1, 3 ) = -1f32 * (eye[0]*v[0] + eye[1]*v[1] + eye[2]*v[2]);
48    *camera_view.index_mut( 2, 0 ) = n[0];
49    *camera_view.index_mut( 2, 1 ) = n[1];
50    *camera_view.index_mut( 2, 2 ) = n[2];
51    *camera_view.index_mut( 2, 3 ) = -1f32 * (eye[0]*n[0] + eye[1]*n[1] + eye[2]*n[2]);
52    *camera_view.index_mut( 3, 0 ) = 0f32;
53    *camera_view.index_mut( 3, 1 ) = 0f32;
54    *camera_view.index_mut( 3, 2 ) = 0f32;
55    *camera_view.index_mut( 3, 3 ) = 1f32;
56
57    camera_view
58}
59
60pub fn invert_rotate_mat4( input: mat::Mat4<f32> ) -> mat::Mat4<f32> {
61    let mut out = input;
62    for i in 0..3 {
63        for j in 0..3 {
64            *out.index_mut( i, j ) = input.index( j, i );
65        }
66    }
67    out
68}
69
70pub fn invert_z_mat4( input: mat::Mat4<f32> ) -> mat::Mat4<f32> {
71    let mut out = input;
72    *out.index_mut( 2, 3 ) = -1f32 * input.index( 2, 3 );
73    out
74}
75
76pub fn invert_xyz_mat4( input: mat::Mat4<f32> ) -> mat::Mat4<f32> {
77    let mut out = input;
78    *out.index_mut( 0, 3 ) = -1f32 * input.index( 0, 3 );
79    *out.index_mut( 1, 3 ) = -1f32 * input.index( 1, 3 );
80    *out.index_mut( 2, 3 ) = -1f32 * input.index( 2, 3 );
81    out
82}
83
84pub fn identity_mat4() -> mat::Mat4<f32> {
85    mat::Mat4::<f32>::init( [1f32, 0f32, 0f32, 0f32,
86                             0f32, 1f32, 0f32, 0f32,
87                             0f32, 0f32, 1f32, 0f32,
88                             0f32, 0f32, 0f32, 1f32 ],
89                             true )
90}