Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

matrix.cpp

Go to the documentation of this file.
00001 /*        Copyright (C) 2000,2001,2002  Sony Computer Entertainment America
00002           
00003           This file is subject to the terms and conditions of the GNU Lesser
00004           General Public License Version 2.1. See the file "COPYING" in the
00005           main directory of this archive for more details.                             */
00006 
00007 #include "ps2s/math.h"
00008 
00009 #include "ps2gl/matrix.h"
00010 #include "ps2gl/glcontext.h"
00011 #include "ps2gl/dlist.h"
00012 #include "ps2gl/immgmanager.h"
00013 #include "ps2gl/dlgmanager.h"
00014 
00015 /********************************************
00016  * CDListMatrixStack
00017  */
00018 
00019 
00020 class CMatrixPopCmd : public CDListCmd {
00021    public:
00022       CMatrixPopCmd() {}
00023       CDListCmd* Play() { glPopMatrix(); return CDListCmd::GetNextCmd(this); }
00024 };
00025 
00026 void
00027 CDListMatrixStack::Pop()
00028 {
00029    GLContext.GetDListGeomManager().Flush();
00030    GLContext.GetDListManager().GetOpenDList() += CMatrixPopCmd();
00031    GLContext.XformChanged();
00032 }
00033 
00034 class CMatrixPushCmd : public CDListCmd {
00035    public:
00036       CMatrixPushCmd() {}
00037       CDListCmd* Play() { glPushMatrix(); return CDListCmd::GetNextCmd(this); }
00038 };
00039 
00040 void
00041 CDListMatrixStack::Push()
00042 {
00043    GLContext.GetDListManager().GetOpenDList() += CMatrixPushCmd();
00044 }
00045 
00046 class CMatrixConcatCmd : public CDListCmd {
00047       cpu_mat_44        Matrix, Inverse;
00048    public:
00049       CMatrixConcatCmd( const cpu_mat_44 &mat, const cpu_mat_44 &inv )
00050          : Matrix(mat), Inverse(inv) {}
00051       CDListCmd* Play() {
00052          pGLContext->GetCurMatrixStack().Concat( Matrix, Inverse );
00053          return CDListCmd::GetNextCmd(this);
00054       }
00055 };
00056 
00057 void
00058 CDListMatrixStack::Concat( const cpu_mat_44& xform, const cpu_mat_44& inverse )
00059 {
00060    GLContext.GetDListGeomManager().Flush();
00061    GLContext.GetDListManager().GetOpenDList() += CMatrixConcatCmd( xform, inverse );
00062    GLContext.XformChanged();
00063 }
00064 
00065 class CMatrixSetTopCmd : public CDListCmd {
00066       cpu_mat_44        Matrix, Inverse;
00067    public:
00068       CMatrixSetTopCmd( const cpu_mat_44 &mat, const cpu_mat_44 &inv )
00069          : Matrix(mat), Inverse(inv) {}
00070       CDListCmd* Play() {
00071          pGLContext->GetCurMatrixStack().SetTop( Matrix, Inverse );
00072          return CDListCmd::GetNextCmd(this);
00073       }
00074 };
00075 
00076 void
00077 CDListMatrixStack::SetTop( const cpu_mat_44 &newMat, const cpu_mat_44 &newInv )
00078 {
00079    GLContext.GetDListGeomManager().Flush();
00080    GLContext.GetDListManager().GetOpenDList() += CMatrixSetTopCmd( newMat, newInv );
00081    GLContext.XformChanged();
00082 }
00083 
00084 
00085 /********************************************
00086  * gl api
00087  */
00088 
00089 void glMatrixMode( GLenum mode )
00090 {
00091    pGLContext->SetMatrixMode( mode );
00092 }
00093 
00094 void glLoadIdentity( void )
00095 {
00096    CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00097 
00098    cpu_mat_44 ident;
00099    ident.set_identity();
00100    matStack.SetTop( ident, ident );
00101 }
00102 
00103 void glPushMatrix( void )
00104 {
00105    CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00106    matStack.Push();
00107 }
00108 
00109 void glPopMatrix( void )
00110 {
00111    CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00112    matStack.Pop();
00113 }
00114 
00115 // courtesy the lovely folks at Intel
00116 extern void Invert2( float *mat, float *dst );
00117 
00118 void glLoadMatrixf( const GLfloat *m )
00119 {
00120    CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00121    cpu_mat_44 newMat;
00122 
00123    // unfortunately we can't assume the matrix is qword-aligned
00124    float *dest = reinterpret_cast<float*>(&newMat);
00125    for ( int i = 0; i < 16; i++ )
00126       *dest++ = *m++;
00127 
00128    cpu_mat_44 invMatrix;
00129    Invert2( (float*)&newMat, (float*)&invMatrix );
00130 
00131    matStack.SetTop( newMat, invMatrix );
00132 }
00133 
00134 void glFrustum( GLdouble left, GLdouble right,
00135                 GLdouble bottom, GLdouble top,
00136                 GLdouble zNear, GLdouble zFar )
00137 {
00138    cpu_mat_44 xform( cpu_vec_xyzw( (2.0f * zNear)
00139                                    / (right - left),
00140                                    0.0f,
00141                                    0.0f,
00142                                    0.0f ),
00143                      cpu_vec_xyzw( 0.0f,
00144                                    (2.0f * zNear)
00145                                    / (top - bottom),
00146                                    0.0f,
00147                                    0.0f ),
00148                      cpu_vec_xyzw( (right + left)
00149                                    / (right - left),
00150                                    (top + bottom)
00151                                    / (top - bottom),
00152                                    -(zFar + zNear)
00153                                    / (zFar - zNear),
00154                                    -1.0f ),
00155                      cpu_vec_xyzw( 0.0f,
00156                                    0.0f,
00157                                    (-2.0f * zFar * zNear)
00158                                    / (zFar - zNear),
00159                                    0.0f )
00160       );
00161 
00162    cpu_mat_44 inv( cpu_vec_xyzw( (right - left)
00163                                  / (2 * zNear),
00164                                  0,
00165                                  0,
00166                                  0 ),
00167                    cpu_vec_xyzw( 0,
00168                                  (top - bottom)
00169                                  / (2 * zNear),
00170                                  0,
00171                                  0 ),
00172                    cpu_vec_xyzw( 0,
00173                                  0,
00174                                  0,
00175                                  -(zFar - zNear)
00176                                  / (2 * zFar * zNear) ),
00177                    cpu_vec_xyzw( (right + left)
00178                                  / (2 * zNear),
00179                                  (top + bottom)
00180                                  / (2 * zNear),
00181                                  -1,
00182                                  (zFar + zNear)
00183                                  / (2 * zFar * zNear) )
00184       );
00185 
00186    CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00187    matStack.Concat( xform, inv );
00188 }
00189 
00190 void glOrtho( GLdouble left, GLdouble right,
00191               GLdouble bottom, GLdouble top,
00192               GLdouble zNear, GLdouble zFar )
00193 {
00194    cpu_mat_44 xform( cpu_vec_xyzw( (2.0f)
00195                                    / (right - left),
00196                                    0.0f,
00197                                    0.0f,
00198                                    0.0f ),
00199                      cpu_vec_xyzw( 0.0f,
00200                                    (2.0f)
00201                                    / (top - bottom),
00202                                    0.0f,
00203                                    0.0f ),
00204                      cpu_vec_xyzw( 0.0f,
00205                                    0.0f,
00206                                    -2
00207                                    / (zFar - zNear),
00208                                    0.0f ),
00209                      cpu_vec_xyzw( - (right + left)
00210                                    / (right - left),
00211                                    - (top + bottom)
00212                                    / (top - bottom),
00213                                    - (zFar + zNear)
00214                                    / (zFar - zNear),
00215                                    1.0f )
00216       );
00217 
00218    cpu_mat_44 inv( cpu_vec_xyzw( (right - left)
00219                                  / 2,
00220                                  0,
00221                                  0,
00222                                  0 ),
00223                    cpu_vec_xyzw( 0,
00224                                  (top - bottom)
00225                                  / 2,
00226                                  0,
00227                                  0 ),
00228                    cpu_vec_xyzw( 0,
00229                                  0,
00230                                  (zFar - zNear)
00231                                  / -2,
00232                                  0 ),
00233                    cpu_vec_xyzw( (right + left)
00234                                  / 2,
00235                                  (top + bottom)
00236                                  / 2,
00237                                  (zFar + zNear)
00238                                  / 2,
00239                                  1 )
00240       );
00241 
00242    CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00243    matStack.Concat( xform, inv );
00244 }
00245 
00246 void glMultMatrixf( const GLfloat *m )
00247 {
00248    // unfortunately we can't assume the matrix is qword-aligned
00249    // the casts to float below fix an apparent parse error... something's up here..
00250    cpu_mat_44 newMatrix( cpu_vec_xyzw( (float)m[0], (float)m[1], (float)m[2], (float)m[3] ),
00251                          cpu_vec_xyzw( (float)m[4], (float)m[5], (float)m[6], (float)m[7] ),
00252                          cpu_vec_xyzw( (float)m[8], (float)m[9], (float)m[10], (float)m[11] ),
00253                          cpu_vec_xyzw( (float)m[12], (float)m[13], (float)m[14], (float)m[15] ) );
00254 
00255    // close your eyes.. this is a temporary hack
00256 
00257    /*
00258    // assume that newMatrix consists of rotations, uniform scales, and translations
00259    cpu_vec_xyzw scaledVec( 1, 0, 0, 0 );
00260    scaledVec = newMatrix * scaledVec;
00261    float scale = scaledVec.length();
00262 
00263    cpu_mat_44 invMatrix = newMatrix;
00264    invMatrix.set_col3( cpu_vec_xyzw(0,0,0,0) );
00265    invMatrix.transpose_in_place();
00266    invMatrix.set_col3( -newMatrix.get_col3() );
00267    cpu_mat_44 scaleMat;
00268    scaleMat.set_scale( cpu_vec_xyz(scale, scale, scale) );
00269    invMatrix = scaleMat * invMatrix;
00270    */
00271 
00272    cpu_mat_44 invMatrix;
00273 //     invMatrix.set_identity();
00274    Invert2( (float*)&newMatrix, (float*)&invMatrix );
00275    CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00276    matStack.Concat( newMatrix, invMatrix );
00277 
00278 //     mWarn( "glMultMatrix is not correct" );
00279 
00280 }
00281 
00282 void glRotatef( GLfloat angle,
00283                 GLfloat x, GLfloat y, GLfloat z )
00284 {
00285    cpu_mat_44 xform, inverse;
00286    cpu_vec_xyz axis(x,y,z);
00287    axis.normalize();
00288    xform.set_rotate( Math::DegToRad(angle), axis );
00289    inverse.set_rotate( Math::DegToRad(-angle), axis );
00290 
00291    CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00292    matStack.Concat( xform, inverse );
00293 }
00294 
00295 void glScalef( GLfloat x, GLfloat y, GLfloat z )
00296 {
00297    cpu_mat_44 xform, inverse;
00298    xform.set_scale( cpu_vec_xyz(x,y,z) );
00299    inverse.set_scale( cpu_vec_xyz(1.0f/x, 1.0f/y, 1.0f/z) );
00300 
00301    CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00302    matStack.Concat( xform, inverse );
00303 }
00304 
00305 void glTranslatef( GLfloat x, GLfloat y, GLfloat z )
00306 {
00307    cpu_mat_44 xform, inverse;
00308    cpu_vec_xyz direction(x, y, z);
00309    xform.set_translate( direction );
00310    inverse.set_translate( -direction );
00311 
00312    CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00313    matStack.Concat( xform, inverse );
00314 }

ps2gl version cvs