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 void glLoadMatrixf( const GLfloat *m )
00116 {
00117    CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00118    cpu_mat_44 newMat;
00119 
00120    // unfortunately we can't assume the matrix is qword-aligned
00121    float *dest = reinterpret_cast<float*>(&newMat);
00122    for ( int i = 0; i < 16; i++ )
00123       *dest++ = *m++;
00124 
00125    // FIXME: need to compute the inverse
00126    mNotImplemented( "LoadMatrix is broken.. inverses won't be correct." );
00127    cpu_mat_44 dummy;
00128    matStack.SetTop( newMat, dummy );
00129 }
00130 
00131 void glFrustum( GLdouble left, GLdouble right,
00132                 GLdouble bottom, GLdouble top,
00133                 GLdouble zNear, GLdouble zFar )
00134 {
00135    cpu_mat_44 xform( cpu_vec_xyzw( (2.0f * zNear)
00136                                    / (right - left),
00137                                    0.0f,
00138                                    0.0f,
00139                                    0.0f ),
00140                      cpu_vec_xyzw( 0.0f,
00141                                    (2.0f * zNear)
00142                                    / (top - bottom),
00143                                    0.0f,
00144                                    0.0f ),
00145                      cpu_vec_xyzw( (right + left)
00146                                    / (right - left),
00147                                    (top + bottom)
00148                                    / (top - bottom),
00149                                    -(zFar + zNear)
00150                                    / (zFar - zNear),
00151                                    -1.0f ),
00152                      cpu_vec_xyzw( 0.0f,
00153                                    0.0f,
00154                                    (-2.0f * zFar * zNear)
00155                                    / (zFar - zNear),
00156                                    0.0f )
00157       );
00158 
00159    cpu_mat_44 inv( cpu_vec_xyzw( (right - left)
00160                                  / (2 * zNear),
00161                                  0,
00162                                  0,
00163                                  0 ),
00164                    cpu_vec_xyzw( 0,
00165                                  (top - bottom)
00166                                  / (2 * zNear),
00167                                  0,
00168                                  0 ),
00169                    cpu_vec_xyzw( 0,
00170                                  0,
00171                                  0,
00172                                  -(zFar - zNear)
00173                                  / (2 * zFar * zNear) ),
00174                    cpu_vec_xyzw( (right + left)
00175                                  / (2 * zNear),
00176                                  (top + bottom)
00177                                  / (2 * zNear),
00178                                  -1,
00179                                  (zFar + zNear)
00180                                  / (2 * zFar * zNear) )
00181       );
00182 
00183    CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00184    matStack.Concat( xform, inv );
00185 }
00186 
00187 void glOrtho( GLdouble left, GLdouble right,
00188               GLdouble bottom, GLdouble top,
00189               GLdouble zNear, GLdouble zFar )
00190 {
00191    cpu_mat_44 xform( cpu_vec_xyzw( (2.0f)
00192                                    / (right - left),
00193                                    0.0f,
00194                                    0.0f,
00195                                    0.0f ),
00196                      cpu_vec_xyzw( 0.0f,
00197                                    (2.0f)
00198                                    / (top - bottom),
00199                                    0.0f,
00200                                    0.0f ),
00201                      cpu_vec_xyzw( 0.0f,
00202                                    0.0f,
00203                                    -2
00204                                    / (zFar - zNear),
00205                                    0.0f ),
00206                      cpu_vec_xyzw( - (right + left)
00207                                    / (right - left),
00208                                    - (top + bottom)
00209                                    / (top - bottom),
00210                                    - (zFar + zNear)
00211                                    / (zFar - zNear),
00212                                    1.0f )
00213       );
00214 
00215    cpu_mat_44 inv( cpu_vec_xyzw( (right - left)
00216                                  / 2,
00217                                  0,
00218                                  0,
00219                                  0 ),
00220                    cpu_vec_xyzw( 0,
00221                                  (top - bottom)
00222                                  / 2,
00223                                  0,
00224                                  0 ),
00225                    cpu_vec_xyzw( 0,
00226                                  0,
00227                                  (zFar - zNear)
00228                                  / -2,
00229                                  0 ),
00230                    cpu_vec_xyzw( (right + left)
00231                                  / 2,
00232                                  (top + bottom)
00233                                  / 2,
00234                                  (zFar + zNear)
00235                                  / 2,
00236                                  1 )
00237       );
00238 
00239    CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00240    matStack.Concat( xform, inv );
00241 }
00242 
00243 // courtesy the lovely folks at Intel
00244 extern void Invert2( float *mat, float *dst );
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