matrix.cpp

Go to the documentation of this file.
00001 /*
00002     RenderStack  Support library for OpenGL 3+
00003     Copyright (C) 2010  Timo Suoranta
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Lesser General Public
00007     License as published by the Free Software Foundation; either
00008     version 2.1 of the License, or (at your option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Lesser General Public License for more details.
00014 
00015     You should have received a copy of the GNU Lesser General Public
00016     License along with this library; if not, write to the Free Software
00017     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00018 */
00019 
00027 #include "renderstack/matrix.hpp"
00028 #include "renderstack/quaternion.hpp"
00029 
00030 #include <math.h>
00031 
00032 namespace renderstack {
00033 
00034 
00035 void matrix::set_row(int row, vec4 const &v)
00036 {
00037     m[0][row] = v.x;
00038     m[1][row] = v.y;
00039     m[2][row] = v.z;
00040     m[3][row] = v.w;
00041 }
00042 
00043 vec4 matrix::row(int row) const
00044 {
00045     return vec4(
00046         m[0][row],
00047         m[1][row],
00048         m[2][row],
00049         m[3][row]
00050     );
00051 }
00052 
00053 vec3 matrix::column3(int col) const
00054 {
00055     return vec3(
00056         m[col][0],
00057         m[col][1],
00058         m[col][2]
00059     );
00060 }
00061 
00062 vec4 matrix::column(int col) const
00063 {
00064     return vec4(
00065         m[col][0],
00066         m[col][1],
00067         m[col][2],
00068         m[col][3]
00069     );
00070 }
00071 
00072 void matrix::set_column(int col, vec4 const &v)
00073 {
00074     m[col][0] = v.x;
00075     m[col][1] = v.y;
00076     m[col][2] = v.z;
00077     m[col][3] = v.w;
00078 }
00079 
00080 vec3 matrix::transform_vector(vec3 const &v) const
00081 {
00082     return vec3(
00083         m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z + m[3][0],
00084         m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z + m[3][1],
00085         m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z + m[3][2]
00086     );
00087 }
00088 
00089 vec4 matrix::transform_vector(vec4 const &v) const
00090 {
00091     return vec4(
00092         m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z + m[3][0] * v.w,
00093         m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z + m[3][1] * v.w,
00094         m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z + m[3][2] * v.w,
00095         m[0][3] * v.x + m[1][3] * v.y + m[2][3] * v.z + m[3][3] * v.w
00096     );
00097 }
00098 
00099 vec3 matrix::uniform_transform_direction(vec3 const &v) const
00100 {
00101     return vec3(
00102         m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z,
00103         m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z,
00104         m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z
00105     );
00106 }
00107 
00108 
00109 matrix::matrix(quaternion const &q)
00110 {
00111     float x2 = 2.0f * q.x;
00112     float y2 = 2.0f * q.y;
00113     float z2 = 2.0f * q.z;
00114     float xx = q.x * x2;
00115     float xy = q.x * y2;
00116     float xz = q.x * z2;
00117     float yy = q.y * y2;
00118     float yz = q.y * z2;
00119     float zz = q.z * z2;
00120     float wx = q.w * x2;
00121     float wy = q.w * y2;
00122     float wz = q.w * z2;
00123 
00124     m[0][0] = 1.0f - yy - zz;   m[1][0] = xy - wz;          m[2][0] = xz + wy;          m[3][0] = 0.0f; 
00125     m[0][1] = xy + wz;          m[1][1] = 1.0f - xx - zz;   m[2][1] = yz - wx;          m[3][1] = 0.0f; 
00126     m[0][2] = xz - wy;          m[1][2] = yz + wx;          m[2][2] = 1.0f - xx - yy;   m[3][2] = 0.0f;
00127     m[0][3] = 0.0f;             m[1][3] = 0.0f;             m[2][3] = 0.0f;             m[3][3] = 1.0f;
00128 
00129 }
00130 
00131 matrix matrix::operator*(matrix const &other) const
00132 {
00133     return matrix(
00134         m[0][0] * other.m[0][0] + m[1][0] * other.m[0][1] + m[2][0] * other.m[0][2] + m[3][0] * other.m[0][3],
00135         m[0][0] * other.m[1][0] + m[1][0] * other.m[1][1] + m[2][0] * other.m[1][2] + m[3][0] * other.m[1][3],
00136         m[0][0] * other.m[2][0] + m[1][0] * other.m[2][1] + m[2][0] * other.m[2][2] + m[3][0] * other.m[2][3],
00137         m[0][0] * other.m[3][0] + m[1][0] * other.m[3][1] + m[2][0] * other.m[3][2] + m[3][0] * other.m[3][3],
00138 
00139         m[0][1] * other.m[0][0] + m[1][1] * other.m[0][1] + m[2][1] * other.m[0][2] + m[3][1] * other.m[0][3],
00140         m[0][1] * other.m[1][0] + m[1][1] * other.m[1][1] + m[2][1] * other.m[1][2] + m[3][1] * other.m[1][3],
00141         m[0][1] * other.m[2][0] + m[1][1] * other.m[2][1] + m[2][1] * other.m[2][2] + m[3][1] * other.m[2][3],
00142         m[0][1] * other.m[3][0] + m[1][1] * other.m[3][1] + m[2][1] * other.m[3][2] + m[3][1] * other.m[3][3],
00143 
00144         m[0][2] * other.m[0][0] + m[1][2] * other.m[0][1] + m[2][2] * other.m[0][2] + m[3][2] * other.m[0][3],
00145         m[0][2] * other.m[1][0] + m[1][2] * other.m[1][1] + m[2][2] * other.m[1][2] + m[3][2] * other.m[1][3],
00146         m[0][2] * other.m[2][0] + m[1][2] * other.m[2][1] + m[2][2] * other.m[2][2] + m[3][2] * other.m[2][3],
00147         m[0][2] * other.m[3][0] + m[1][2] * other.m[3][1] + m[2][2] * other.m[3][2] + m[3][2] * other.m[3][3],
00148 
00149         m[0][3] * other.m[0][0] + m[1][3] * other.m[0][1] + m[2][3] * other.m[0][2] + m[3][3] * other.m[0][3],
00150         m[0][3] * other.m[1][0] + m[1][3] * other.m[1][1] + m[2][3] * other.m[1][2] + m[3][3] * other.m[1][3],
00151         m[0][3] * other.m[2][0] + m[1][3] * other.m[2][1] + m[2][3] * other.m[2][2] + m[3][3] * other.m[2][3],
00152         m[0][3] * other.m[3][0] + m[1][3] * other.m[3][1] + m[2][3] * other.m[3][2] + m[3][3] * other.m[3][3]
00153     );
00154 }
00155 
00156 
00157 matrix inverse(matrix const &m)
00158 {
00159     vec4  x  = m.column(0);
00160     vec4  y  = m.column(1);
00161     vec4  z  = m.column(2);
00162     vec4  w  = m.column(3);
00163     vec4  x1 = cross(y, z, w);
00164     vec4  y1 = cross(z, w, x);
00165     vec4  z1 = cross(w, x, y);
00166     vec4  w1 = cross(x, y, z);
00167     float lx = dot(x, x1);
00168     float ly = dot(y, y1);
00169     float lz = dot(z, z1);
00170     float lw = dot(w, w1);
00171 
00172     if(
00173         RS_NEAR_ZERO(lx) ||
00174         RS_NEAR_ZERO(ly) ||
00175         RS_NEAR_ZERO(lz) ||
00176         RS_NEAR_ZERO(lw)
00177     )
00178     {
00179         throw matrix_not_invertible_exception();
00180     }
00181 
00182     x1[0] /= lx; 
00183     y1[0] /= ly; 
00184     z1[0] /= lz; 
00185     w1[0] /= lw; 
00186 
00187     return matrix(x1, y1, z1, w1);
00188 }
00189 
00190 
00191 matrix make_matrix_frustum_centered(
00192     float width,
00193     float height,
00194     float nearv,
00195     float farv
00196 )
00197 {
00198     float far_plus_near  = farv + nearv;
00199     float far_minus_near = farv - nearv;
00200     float far_times_near = farv * nearv;
00201 
00202     float x = RS_NEAR_ZERO(width         ) ? 1.0f : ( 2.0f *  nearv          / width);
00203     float y = RS_NEAR_ZERO(height        ) ? 1.0f : ( 2.0f *  nearv          / height);
00204     float c = RS_NEAR_ZERO(far_minus_near) ? 1.0f : (        -far_plus_near  / far_minus_near);
00205     float d = RS_NEAR_ZERO(far_minus_near) ? 1.0f : (-2.0f *  far_times_near / far_minus_near);
00206 
00207     return matrix(
00208         x,     0.0f,   0.0f,  0.0f,
00209         0.0f,  y,      0.0f,  0.0f,
00210         0.0f,  0.0f,   c,     d,
00211         0.0f,  0.0f,  -1.0f,  0.0f
00212     );
00213 }
00214 
00215 
00216 matrix make_matrix_frustum(
00217     float left,
00218     float right,
00219     float bottom,
00220     float top,
00221     float nearv,
00222     float farv
00223 )
00224 {
00225     float right_plus_left  = right + left;
00226     float top_plus_bottom  = top   + bottom;
00227     float far_plus_near    = farv  + nearv;
00228     float right_minus_left = right - left;
00229     float top_minus_bottom = top   - bottom;
00230     float far_minus_near   = farv  - nearv;
00231     float far_times_near   = farv  * nearv;
00232 
00233     float x = RS_NEAR_ZERO(right_minus_left) ? 1.0f : ( 2.0f * nearv          / right_minus_left);
00234     float y = RS_NEAR_ZERO(top_minus_bottom) ? 1.0f : ( 2.0f * nearv          / top_minus_bottom);
00235     float a = RS_NEAR_ZERO(right_minus_left) ? 1.0f : ( right_plus_left       / right_minus_left);
00236     float b = RS_NEAR_ZERO(top_minus_bottom) ? 1.0f : ( top_plus_bottom       / top_minus_bottom);
00237     float c = RS_NEAR_ZERO(far_minus_near  ) ? 1.0f : (-far_plus_near         / far_minus_near);
00238     float d = RS_NEAR_ZERO(far_minus_near  ) ? 1.0f : (-2.0f * far_times_near / far_minus_near);
00239 
00240     return matrix(
00241         x,     0.0f,   a,     0.0f,
00242         0.0f,  y,      b,     0.0f,
00243         0.0f,  0.0f,   c,     d,
00244         0.0f,  0.0f,  -1.0f,  0.0f
00245     );
00246 }
00247 
00248 
00249 matrix make_matrix_perspective_vertical(
00250     float fov_y_radians,
00251     float aspect,
00252     float near_val,
00253     float far_val
00254 )
00255 {
00256     float fov_tangent = tanf(fov_y_radians * 0.5f);
00257     float height      = 2.0f * near_val * fov_tangent;
00258     float width       = height * aspect;
00259 
00260     return make_matrix_frustum_centered(width, height, near_val, far_val);
00261 }
00262 
00263 matrix make_matrix_perspective_horizontal(
00264     float fov_x_radians,
00265     float aspect,
00266     float near_val,
00267     float far_val
00268 )
00269 {
00270     float fov_tangent = tanf(fov_x_radians * 0.5f);
00271     float width       = 2.0f * near_val * fov_tangent;
00272     float height      = width / aspect;
00273 
00274     return make_matrix_frustum_centered(width, height, near_val, far_val);
00275 }
00276 
00277 matrix make_matrix_orthogonal_centered(
00278     float width,
00279     float height,
00280     float near_val,
00281     float far_val
00282 )
00283 {
00284     float x = RS_NEAR_ZERO(width            ) ? 1.0f : ( 2.0f / (float)(width)             );
00285     float y = RS_NEAR_ZERO(height           ) ? 1.0f : ( 2.0f / (float)(height)            );
00286     float z = RS_TOLERANCE(near_val, far_val) ? 1.0f : (-2.0f / (float)(far_val - near_val));
00287 
00288     return matrix(
00289         x,     0.0f,  0.0f,  0.0f,
00290         0.0f,  y,     0.0f,  0.0f,
00291         0.0f,  0.0f,  z,     0.0f,
00292         0.0f,  0.0f,  0.0f,  1.0f
00293     );
00294 }
00295 
00296 matrix make_matrix_orthogonal(
00297     float left,
00298     float right,
00299     float bottom,
00300     float top,
00301     float near_val,
00302     float far_val
00303 )
00304 {
00305     float r_plus_l  = right   + left;
00306     float t_plus_b  = top     + bottom;
00307     float f_plus_n  = far_val + near_val;
00308     float r_minus_l = right   - left;
00309     float t_minus_b = top     - bottom;
00310     float f_minus_n = far_val - near_val;
00311 
00312     float x  = RS_NEAR_ZERO(r_minus_l) ? 1.0f : ( 2.0f     / r_minus_l);
00313     float y  = RS_NEAR_ZERO(t_minus_b) ? 1.0f : ( 2.0f     / t_minus_b);
00314     float z  = RS_NEAR_ZERO(f_minus_n) ? 1.0f : (-2.0f     / f_minus_n);
00315     float tx = RS_NEAR_ZERO(r_minus_l) ? 0.0f : (-r_plus_l / r_minus_l);
00316     float ty = RS_NEAR_ZERO(t_minus_b) ? 0.0f : (-t_plus_b / t_minus_b);
00317     float tz = RS_NEAR_ZERO(f_minus_n) ? 0.0f : (-f_plus_n / f_minus_n);
00318 
00319     return matrix(
00320         x,     0.0f,  0,     tx,
00321         0.0f,  y,     0,     ty,
00322         0.0f,  0.0f,  z,     tz,
00323         0.0f,  0.0f,  0.0f,  1.0f
00324     );
00325 }
00326 
00327 void make_matrix_quaternion_xyz(
00328     matrix           &m,
00329     matrix           &mi,
00330     quaternion const &q,
00331     vec3       const &t
00332 )
00333 {
00334     float x2 = 2.0f * q.x;
00335     float y2 = 2.0f * q.y;
00336     float z2 = 2.0f * q.z;
00337     float xx = q.x * x2;
00338     float xy = q.x * y2;
00339     float xz = q.x * z2;
00340     float yy = q.y * y2;
00341     float yz = q.y * z2;
00342     float zz = q.z * z2;
00343     float wx = q.w * x2;
00344     float wy = q.w * y2;
00345     float wz = q.w * z2;
00346 
00347     mi.m[0][0] = m.m[0][0] = 1.0f - yy - zz;
00348     mi.m[0][1] = m.m[1][0] = xy - wz;
00349     mi.m[0][2] = m.m[2][0] = xz + wy;
00350                  m.m[3][0] = t.x;
00351 
00352     mi.m[1][0] = m.m[0][1] = xy + wz;
00353     mi.m[1][1] = m.m[1][1] = 1.0f - xx - zz;
00354     mi.m[1][2] = m.m[2][1] = yz - wx;
00355                  m.m[3][1] = t.y;
00356 
00357     mi.m[2][0] = m.m[0][2] = xz - wy;
00358     mi.m[2][1] = m.m[1][2] = yz + wx;
00359     mi.m[2][2] = m.m[2][2] = 1.0f - xx - yy;
00360                  m.m[3][2] = t.z;
00361 
00362     mi.m[3][0] = mi.m[0][0] * -t.x + mi.m[1][0] * -t.y + mi.m[2][0] * -t.z;
00363     mi.m[3][1] = mi.m[0][1] * -t.x + mi.m[1][1] * -t.y + mi.m[2][1] * -t.z;
00364     mi.m[3][2] = mi.m[0][2] * -t.x + mi.m[1][2] * -t.y + mi.m[2][2] * -t.z;
00365 
00366     mi.m[3][3] = m.m[3][3] = 1.0f;
00367 }
00368 
00369 void make_matrix_quaternion_xyz(
00370     matrix           &m,
00371     matrix           &mi,
00372     quaternion const &q,
00373     vec3       const &t,
00374     vec3       const &s
00375 )
00376 {
00377     float x2 = 2.0f * q.x;
00378     float y2 = 2.0f * q.y;
00379     float z2 = 2.0f * q.z;
00380     float xx = q.x * x2;
00381     float xy = q.x * y2;
00382     float xz = q.x * z2;
00383     float yy = q.y * y2;
00384     float yz = q.y * z2;
00385     float zz = q.z * z2;
00386     float wx = q.w * x2;
00387     float wy = q.w * y2;
00388     float wz = q.w * z2;
00389 
00390     mi.m[0][0] = m.m[0][0] = 1.0f - yy - zz;
00391     mi.m[0][1] = m.m[1][0] = xy - wz;
00392     mi.m[0][2] = m.m[2][0] = xz + wy;
00393                  m.m[3][0] = t.x;
00394 
00395     mi.m[1][0] = m.m[0][1] = xy + wz;
00396     mi.m[1][1] = m.m[1][1] = 1.0f - xx - zz;
00397     mi.m[1][2] = m.m[2][1] = yz - wx;
00398                  m.m[3][1] = t.y;
00399 
00400     mi.m[2][0] = m.m[0][2] = xz - wy;
00401     mi.m[2][1] = m.m[1][2] = yz + wx;
00402     mi.m[2][2] = m.m[2][2] = 1.0f - xx - yy;
00403                  m.m[3][2] = t.z;
00404 
00405     mi.m[3][0] = mi.m[0][0] * -t.x + mi.m[1][0] * -t.y + mi.m[2][0] * -t.z;
00406     mi.m[3][1] = mi.m[0][1] * -t.x + mi.m[1][1] * -t.y + mi.m[2][1] * -t.z;
00407     mi.m[3][2] = mi.m[0][2] * -t.x + mi.m[1][2] * -t.y + mi.m[2][2] * -t.z;
00408 
00409     m.m[0][0] = m.m[0][0] * s.x;
00410     m.m[1][0] = m.m[1][0] * s.y;
00411     m.m[2][0] = m.m[2][0] * s.z;
00412 
00413     m.m[0][1] = m.m[0][1] * s.x;
00414     m.m[1][1] = m.m[1][1] * s.y;
00415     m.m[2][1] = m.m[2][1] * s.z;
00416 
00417     m.m[0][2] = m.m[0][2] * s.x;
00418     m.m[1][2] = m.m[1][2] * s.y;
00419     m.m[2][2] = m.m[2][2] * s.z;
00420 
00421     {
00422         float isx = RS_NEAR_ZERO(s.x) ? 0.0f : 1.0f / s.x;
00423         float isy = RS_NEAR_ZERO(s.y) ? 0.0f : 1.0f / s.y;
00424         float isz = RS_NEAR_ZERO(s.z) ? 0.0f : 1.0f / s.z;
00425 
00426         mi.m[0][0] = mi.m[0][0] * isx;
00427         mi.m[1][0] = mi.m[1][0] * isy;
00428         mi.m[2][0] = mi.m[2][0] * isz;
00429 
00430         mi.m[0][1] = mi.m[0][1] * isx;
00431         mi.m[1][1] = mi.m[1][1] * isy;
00432         mi.m[2][1] = mi.m[2][1] * isz;
00433 
00434         mi.m[0][2] = mi.m[0][2] * isx;
00435         mi.m[1][2] = mi.m[1][2] * isy;
00436         mi.m[2][2] = mi.m[2][2] * isz;
00437     }
00438     m.m[0][3] = mi.m[0][3] = 0.0f;
00439     m.m[1][3] = mi.m[1][3] = 0.0f;
00440     m.m[2][3] = mi.m[2][3] = 0.0f;
00441     m.m[3][3] = mi.m[3][3] = 1.0f;
00442 }
00443 
00444 matrix matrix_make_translate_scale(
00445     vec3 const &t,
00446     vec3 const &s
00447 )
00448 {
00449     return matrix(
00450         s.x,  0.0f, 0.0f, t.x,
00451         0.0f, s.y,  0.0f, t.y,
00452         0.0f, 0.0f, s.z,  t.z,
00453         0.0f, 0.0f, 0.0f, 1.0f
00454     );
00455 }
00456 
00457 matrix matrix_make_scale(
00458     vec3 const &s
00459 )
00460 {
00461     return matrix(
00462         s.x,  0.0f, 0.0f, 0.0f,
00463         0.0f, s.y,  0.0f, 0.0f,
00464         0.0f, 0.0f, s.z,  0.0f,
00465         0.0f, 0.0f, 0.0f, 1.0f
00466     );
00467 }
00468 
00469 matrix matrix_make_translate(
00470     vec3 const &t
00471 )
00472 {
00473     return matrix(
00474         1.0f, 0.0f, 0.0f, t.x,
00475         0.0f, 1.0f, 0.0f, t.y,
00476         0.0f, 0.0f, 1.0f, t.z,
00477         0.0f, 0.0f, 0.0f, 1.0f
00478     );
00479 }
00480 
00481 void make_matrix_hpb_xyz(
00482     matrix       &m,
00483     matrix       &mi,
00484     vec3   const &hpb,
00485     vec3   const &t
00486 )
00487 {
00488     float A = cosf(hpb.y);
00489     float B = sinf(hpb.y);
00490     float C = cosf(hpb.x);
00491     float D = sinf(hpb.x);
00492     float E = cosf(hpb.z);
00493     float F = sinf(hpb.z);
00494 
00495     {
00496         float DB = D * B;
00497 
00498         mi.m[0][0] = m.m[0][0] =  C *  E + -DB * F;
00499         mi.m[0][1] = m.m[1][0] =  C * -F + -DB * E;
00500         mi.m[0][2] = m.m[2][0] = -D *  A;
00501                      m.m[3][0] =  t.x;
00502     }
00503 
00504     {
00505         mi.m[1][0] = m.m[0][1] =  A * F;
00506         mi.m[1][1] = m.m[1][1] =  A * E;
00507         mi.m[1][2] = m.m[2][1] = -B;
00508                      m.m[3][1] =  t.y;
00509     }
00510 
00511     {
00512         float CB = C * B;
00513 
00514         mi.m[2][0] = m.m[0][2] =  D *  E + CB * F;
00515         mi.m[2][1] = m.m[1][2] =  D * -F + CB * E;
00516         mi.m[2][2] = m.m[2][2] =  C *  A;
00517                      m.m[3][2] =  t.z;
00518     }
00519 
00520     mi.m[3][0] = mi.m[0][0] * -t.x + mi.m[1][0] * -t.y + mi.m[2][0] * -t.z;
00521     mi.m[3][1] = mi.m[0][1] * -t.x + mi.m[1][1] * -t.y + mi.m[2][1] * -t.z;
00522     mi.m[3][2] = mi.m[0][2] * -t.x + mi.m[1][2] * -t.y + mi.m[2][2] * -t.z;
00523     mi.m[3][3] = 1.0f;
00524     m.m[0][3] = 0.0f;
00525     m.m[1][3] = 0.0f;
00526     m.m[2][3] = 0.0f;
00527     m.m[3][3] = 1.0f;
00528 }
00529 
00530 void make_matrix_hpb_xyz_scale(
00531     matrix       &m,
00532     matrix       &mi,
00533     vec3   const &hpb,
00534     vec3   const &t,
00535     vec3   const &s
00536 )
00537 {
00538     float A = cosf(hpb.y);
00539     float B = sinf(hpb.y);
00540     float C = cosf(hpb.x);
00541     float D = sinf(hpb.x);
00542     float E = cosf(hpb.z);
00543     float F = sinf(hpb.z);
00544 
00545     {
00546         float DB = D * B;
00547 
00548         mi.m[0][0] = m.m[0][0] =  C *  E + -DB * F;
00549         mi.m[0][1] = m.m[1][0] =  C * -F + -DB * E;
00550         mi.m[0][2] = m.m[2][0] = -D *  A;
00551                      m.m[3][0] =  t.x;
00552     }
00553 
00554     {
00555         mi.m[1][0] = m.m[0][1] =  A * F;
00556         mi.m[1][1] = m.m[1][1] =  A * E;
00557         mi.m[1][2] = m.m[2][1] = -B;
00558                      m.m[3][1] =  t.y;
00559     }
00560 
00561     {
00562         float CB = C * B;
00563 
00564         mi.m[2][0] = m.m[0][2] =  D *  E + CB * F;
00565         mi.m[2][1] = m.m[1][2] =  D * -F + CB * E;
00566         mi.m[2][2] = m.m[2][2] =  C *  A;
00567                      m.m[3][2] =  t.z;
00568     }
00569 
00570     mi.m[3][0] = mi.m[0][0] * -t.x + mi.m[1][0] * -t.y + mi.m[2][0] * -t.z;
00571     mi.m[3][1] = mi.m[0][1] * -t.x + mi.m[1][1] * -t.y + mi.m[2][1] * -t.z;
00572     mi.m[3][2] = mi.m[0][2] * -t.x + mi.m[1][2] * -t.y + mi.m[2][2] * -t.z;
00573 
00574     m.m[0][0] = m.m[0][0] * s.x;
00575     m.m[1][0] = m.m[1][0] * s.y;
00576     m.m[2][0] = m.m[2][0] * s.z;
00577 
00578     m.m[0][1] = m.m[0][1] * s.x;
00579     m.m[1][1] = m.m[1][1] * s.y;
00580     m.m[2][1] = m.m[2][1] * s.z;
00581 
00582     m.m[0][2] = m.m[0][2] * s.x;
00583     m.m[1][2] = m.m[1][2] * s.y;
00584     m.m[2][2] = m.m[2][2] * s.z;
00585 
00586     {
00587         float isx = RS_NEAR_ZERO(s.x) ? 0.0f : 1.0f / s.x; 
00588         float isy = RS_NEAR_ZERO(s.y) ? 0.0f : 1.0f / s.y;
00589         float isz = RS_NEAR_ZERO(s.z) ? 0.0f : 1.0f / s.z;
00590 
00591         mi.m[0][0] = mi.m[0][0] * isx;
00592         mi.m[1][0] = mi.m[1][0] * isy;
00593         mi.m[2][0] = mi.m[2][0] * isz;
00594         mi.m[3][0] = mi.m[3][0] * isz;
00595 
00596         mi.m[0][1] = mi.m[0][1] * isx;
00597         mi.m[1][1] = mi.m[1][1] * isy;
00598         mi.m[2][1] = mi.m[2][1] * isz;
00599         mi.m[3][1] = mi.m[3][1] * isz;
00600 
00601         mi.m[0][2] = mi.m[0][2] * isx;
00602         mi.m[1][2] = mi.m[1][2] * isy;
00603         mi.m[2][2] = mi.m[2][2] * isz;
00604         mi.m[3][2] = mi.m[3][2] * isz;
00605     }
00606 
00607     mi.m[3][3] = 1.0f;
00608     m.m[3][3] = 1.0f;
00609 }
00610 
00611 }
00612 
Generated on Sun Apr 11 12:23:08 2010 for RenderStack by  doxygen 1.6.3