00001
00002
00003
00004
00005
00006
00007
00008
00013 #ifndef matrix_projection_h
00014 #define matrix_projection_h
00015
00016 #include <cml/mathlib/checking.h>
00017 #include <cml/mathlib/helper.h>
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 namespace cml {
00029
00031
00033
00038 template < typename E, class A, class B, class L > void
00039 matrix_perspective(matrix<E,A,B,L>& m, E left, E right, E bottom, E top,
00040 E n, E f, Handedness handedness,
00041 ZClip z_clip)
00042 {
00043 typedef matrix<E,A,B,L> matrix_type;
00044 typedef typename matrix_type::value_type value_type;
00045
00046
00047 detail::CheckMatHomogeneous3D(m);
00048
00049 identity_transform(m);
00050
00051 value_type inv_width = value_type(1) / (right - left);
00052 value_type inv_height = value_type(1) / (top - bottom);
00053 value_type inv_depth = value_type(1) / (f - n);
00054 value_type near2 = value_type(2) * n;
00055 value_type s = handedness == left_handed ? 1 : -1;
00056
00057 if (z_clip == z_clip_neg_one) {
00058 m.set_basis_element(2,2,s * (f + n) * inv_depth);
00059 m.set_basis_element(3,2,value_type(-2) * f * n * inv_depth);
00060 } else {
00061 m.set_basis_element(2,2,s * f * inv_depth);
00062 m.set_basis_element(3,2,-s * n * m.basis_element(2,2));
00063 }
00064
00065 m.set_basis_element(0,0,near2 * inv_width );
00066 m.set_basis_element(1,1,near2 * inv_height );
00067 m.set_basis_element(2,0,-s * (right + left) * inv_width );
00068 m.set_basis_element(2,1,-s * (top + bottom) * inv_height);
00069 m.set_basis_element(2,3,s );
00070 m.set_basis_element(3,3,value_type(0) );
00071 }
00072
00077 template < typename E, class A, class B, class L > void
00078 matrix_perspective(matrix<E,A,B,L>& m, E width, E height, E n, E f,
00079 Handedness handedness, ZClip z_clip)
00080 {
00081 typedef matrix<E,A,B,L> matrix_type;
00082 typedef typename matrix_type::value_type value_type;
00083
00084 value_type half_width = width * value_type(.5);
00085 value_type half_height = height * value_type(.5);
00086 matrix_perspective(m, -half_width, half_width,
00087 -half_height, half_height, n, f, handedness, z_clip);
00088 }
00089
00091 template < typename E, class A, class B, class L > void
00092 matrix_perspective_LH(matrix<E,A,B,L>& m, E left, E right, E bottom,
00093 E top, E n, E f, ZClip z_clip)
00094 {
00095 matrix_perspective(m, left, right, bottom, top, n, f,
00096 left_handed, z_clip);
00097 }
00098
00100 template < typename E, class A, class B, class L > void
00101 matrix_perspective_RH(matrix<E,A,B,L>& m, E left, E right, E bottom,
00102 E top, E n, E f, ZClip z_clip)
00103 {
00104 matrix_perspective(m, left, right, bottom, top, n, f,
00105 right_handed, z_clip);
00106 }
00107
00109 template < typename E, class A, class B, class L > void
00110 matrix_perspective_LH(matrix<E,A,B,L>& m, E width, E height, E n,
00111 E f, ZClip z_clip)
00112 {
00113 matrix_perspective(m, width, height, n, f, left_handed, z_clip);
00114 }
00115
00117 template < typename E, class A, class B, class L > void
00118 matrix_perspective_RH(matrix<E,A,B,L>& m, E width, E height, E n,
00119 E f, ZClip z_clip)
00120 {
00121 matrix_perspective(m, width, height, n, f, right_handed, z_clip);
00122 }
00123
00125
00127
00129 template < typename E, class A, class B, class L > void
00130 matrix_perspective_xfov(matrix<E,A,B,L>& m, E xfov, E aspect, E n,
00131 E f, Handedness handedness, ZClip z_clip)
00132 {
00133 typedef matrix<E,A,B,L> matrix_type;
00134 typedef typename matrix_type::value_type value_type;
00135
00136 value_type width = value_type(2) * std::tan(xfov * value_type(.5)) * n;
00137 matrix_perspective(m, width, width / aspect, n, f,
00138 handedness, z_clip);
00139 }
00140
00142 template < typename E, class A, class B, class L > void
00143 matrix_perspective_xfov_LH(matrix<E,A,B,L>& m, E xfov, E aspect, E n,
00144 E f, ZClip z_clip)
00145 {
00146 matrix_perspective_xfov(m,xfov,aspect,n,f,left_handed,z_clip);
00147 }
00148
00150 template < typename E, class A, class B, class L > void
00151 matrix_perspective_xfov_RH(matrix<E,A,B,L>& m, E xfov, E aspect, E n,
00152 E f, ZClip z_clip)
00153 {
00154 matrix_perspective_xfov(m,xfov,aspect,n,f,right_handed,z_clip);
00155 }
00156
00158
00160
00162 template < typename E, class A, class B, class L > void
00163 matrix_perspective_yfov(matrix<E,A,B,L>& m, E yfov, E aspect, E n,
00164 E f, Handedness handedness, ZClip z_clip)
00165 {
00166 typedef matrix<E,A,B,L> matrix_type;
00167 typedef typename matrix_type::value_type value_type;
00168
00169 value_type height = value_type(2) * std::tan(yfov * value_type(.5)) * n;
00170 matrix_perspective(m, height * aspect, height, n, f,
00171 handedness, z_clip);
00172 }
00173
00175 template < typename E, class A, class B, class L > void
00176 matrix_perspective_yfov_LH(matrix<E,A,B,L>& m, E yfov, E aspect, E n,
00177 E f, ZClip z_clip)
00178 {
00179 matrix_perspective_yfov(m,yfov,aspect,n,f,left_handed,z_clip);
00180 }
00181
00183 template < typename E, class A, class B, class L > void
00184 matrix_perspective_yfov_RH(matrix<E,A,B,L>& m, E yfov, E aspect, E n,
00185 E f, ZClip z_clip)
00186 {
00187 matrix_perspective_yfov(m,yfov,aspect,n,f,right_handed,z_clip);
00188 }
00189
00191
00193
00199 template < typename E, class A, class B, class L > void
00200 matrix_orthographic(matrix<E,A,B,L>& m, E left, E right, E bottom, E top,
00201 E n, E f, Handedness handedness,
00202 ZClip z_clip)
00203 {
00204 typedef matrix<E,A,B,L> matrix_type;
00205 typedef typename matrix_type::value_type value_type;
00206
00207
00208 detail::CheckMatHomogeneous3D(m);
00209
00210 identity_transform(m);
00211
00212 value_type inv_width = value_type(1) / (right - left);
00213 value_type inv_height = value_type(1) / (top - bottom);
00214 value_type inv_depth = value_type(1) / (f - n);
00215 value_type s = handedness == left_handed ? 1 : -1;
00216
00217 if (z_clip == z_clip_neg_one) {
00218 m.set_basis_element(2,2,s * value_type(2) * inv_depth);
00219 m.set_basis_element(3,2,-(f + n) * inv_depth);
00220 } else {
00221 m.set_basis_element(2,2,s * inv_depth);
00222 m.set_basis_element(3,2,-n * inv_depth);
00223 }
00224
00225 m.set_basis_element(0,0,value_type(2) * inv_width );
00226 m.set_basis_element(1,1,value_type(2) * inv_height );
00227 m.set_basis_element(3,0,-(right + left) * inv_width );
00228 m.set_basis_element(3,1,-(top + bottom) * inv_height);
00229 }
00230
00232 template < typename E, class A, class B, class L > void
00233 matrix_orthographic(matrix<E,A,B,L>& m, E width, E height, E n, E f,
00234 Handedness handedness, ZClip z_clip)
00235 {
00236 typedef matrix<E,A,B,L> matrix_type;
00237 typedef typename matrix_type::value_type value_type;
00238
00239 value_type half_width = width * value_type(.5);
00240 value_type half_height = height * value_type(.5);
00241 matrix_orthographic(m, -half_width, half_width,
00242 -half_height, half_height, n, f, handedness, z_clip);
00243 }
00244
00246 template < typename E, class A, class B, class L > void
00247 matrix_orthographic_LH(matrix<E,A,B,L>& m, E left, E right, E bottom,
00248 E top, E n, E f, ZClip z_clip)
00249 {
00250 matrix_orthographic(m, left, right, bottom, top, n, f,
00251 left_handed, z_clip);
00252 }
00253
00255 template < typename E, class A, class B, class L > void
00256 matrix_orthographic_RH(matrix<E,A,B,L>& m, E left, E right, E bottom,
00257 E top, E n, E f, ZClip z_clip)
00258 {
00259 matrix_orthographic(m, left, right, bottom, top, n, f,
00260 right_handed, z_clip);
00261 }
00262
00264 template < typename E, class A, class B, class L > void
00265 matrix_orthographic_LH(matrix<E,A,B,L>& m, E width, E height, E n,
00266 E f, ZClip z_clip)
00267 {
00268 matrix_orthographic(m, width, height, n, f, left_handed,
00269 z_clip);
00270 }
00271
00273 template < typename E, class A, class B, class L > void
00274 matrix_orthographic_RH(matrix<E,A,B,L>& m, E width, E height, E n,
00275 E f, ZClip z_clip)
00276 {
00277 matrix_orthographic(m, width, height, n, f, right_handed,
00278 z_clip);
00279 }
00280
00282
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 template < typename E, class A, class B, class L > void
00296 matrix_viewport(matrix<E,A,B,L>& m, E left, E right, E bottom,
00297 E top, ZClip z_clip, E n = E(0), E f = E(1))
00298 {
00299 matrix_orthographic_LH(m, left, right, bottom, top, n, f, z_clip);
00300
00301 m = inverse(m);
00302 }
00303
00305
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320 template < typename E, class A, class B, class L > void
00321 matrix_pick(
00322 matrix<E,A,B,L>& m, E pick_x, E pick_y, E pick_width, E pick_height,
00323 E viewport_x, E viewport_y, E viewport_width, E viewport_height)
00324 {
00325 typedef matrix<E,A,B,L> matrix_type;
00326 typedef typename matrix_type::value_type value_type;
00327
00328
00329 detail::CheckMatHomogeneous3D(m);
00330
00331 identity_transform(m);
00332
00333 value_type inv_width = value_type(1) / pick_width;
00334 value_type inv_height = value_type(1) / pick_height;
00335
00336 m.set_basis_element(0,0,viewport_width*inv_width);
00337 m.set_basis_element(1,1,viewport_height*inv_height);
00338 m.set_basis_element(3,0,
00339 (viewport_width+value_type(2)*(viewport_x-pick_x))*inv_width);
00340 m.set_basis_element(3,1,
00341 (viewport_height+value_type(2)*(viewport_y-pick_y))*inv_height);
00342 }
00343
00344 }
00345
00346 #endif