Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

matrix.cpp

Go to the documentation of this file.
00001 /* -*- mode: c++ -*-
00002    
00003    this file is part of rcssserver3D
00004    Fri May 9 2003
00005    Copyright (C) 2003 Koblenz University
00006    $Id: matrix.cpp,v 1.4 2003/09/08 08:58:53 rollmark Exp $
00007 
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; version 2 of the License.
00011   
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016  
00017    You should have received a copy of the GNU General Public License
00018    along with this program; if not, write to the Free Software
00019    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00020 */
00021 #include "matrix.h"
00022 
00023 #include <cstdio>
00024 
00025 using namespace salt;
00026 
00027 float Matrix::mIdentity[16]=
00028 {
00029     1.0, 0.0, 0.0, 0.0,
00030     0.0, 1.0, 0.0, 0.0,
00031     0.0, 0.0, 1.0, 0.0,
00032     0.0, 0.0, 0.0, 1.0
00033 };
00034 
00035 void Matrix::Dump() const
00036 {
00037     printf("%f %f %f %f\n", m[0], m[4], m[8], m[12]);
00038     printf("%f %f %f %f\n", m[1], m[5], m[9], m[13]);
00039     printf("%f %f %f %f\n", m[2], m[6], m[10], m[14]);
00040     printf("%f %f %f %f\n", m[3], m[7], m[11], m[15]);
00041 }
00042 
00043 
00044 void Matrix::LookAt(const Vector3f & inEye, const Vector3f & inDirection, const Vector3f & inUp)
00045 {
00046     Vector3f forward    = inDirection.Normalized();
00047     Vector3f up         = inUp.Normalized();
00048     Vector3f right      = forward.Cross(up);
00049     right.Normalize();
00050 
00051     up = right.Cross(forward);
00052 
00053     // Make inverse rotation matrix using right, forward, up vectors
00054     Set(       right.x(),  right.y(),     right.z(),    0.0f,
00055                   up.x(),    up.y(),         up.z(),    0.0f,
00056              forward.x(), forward.y(),  forward.z(),    0.0f,
00057                   0.0f,       0.0f,       0.0f, 1.0f);
00058     
00059     Pos() = Rotate(-inEye);
00060 }
00061 
00066 void Matrix::CalcAttenuationNoRotation(const Vector3f &pos, float radius)
00067 {
00068     Matrix tmp1, tmp2;
00069     
00070     // translate to 'light space' ... no rotation needed
00071     tmp1.Translation(-pos);
00072     
00073     // create proper scaling matrix
00074     float invrad = 0.5f / radius;
00075 
00076     tmp2.Identity();
00077     tmp2(0,0) = invrad;
00078     tmp2(1,1) = invrad;
00079     tmp2(2,2) = invrad;
00080     
00081     Identity ();
00082     Translation (Vector3f(0.5f, 0.5f, 0.5f));
00083 
00084     *this *= tmp2 * tmp1;
00085 }
00086 
00087 void Matrix::CalcAttenuationWithRotation(const Matrix &lightWorldMatrix, float radius)
00088 {
00089     Matrix tmp1, tmp2;
00090     
00091     // translate to 'light space' ... this time with rotation
00092     tmp1 = lightWorldMatrix;
00093     tmp1.InvertRotationMatrix();
00094     
00095     // create proper scaling matrix
00096     float invrad = 0.5f / radius;
00097 
00098     tmp2.Identity();
00099     tmp2(0,0) = invrad;
00100     tmp2(1,1) = invrad;
00101     tmp2(2,2) = invrad;
00102     
00103     Identity ();
00104     Translation (Vector3f(0.5f, 0.5f, 0.5f));
00105 
00106     *this *= tmp2 * tmp1;
00107 }
00108 
00109 void Matrix::CalcInfiniteProjection(float width, float height, float fov, float zNear)
00110 {
00111     const float halfWidth   = zNear * (float)tan(gDegToRad(fov*0.5f));
00112     const float halfHeight  = halfWidth * (height/width);
00113 
00114     CalcInfiniteFrustum(-halfWidth, halfWidth, -halfHeight, halfHeight, zNear);
00115 }
00116 
00117 void Matrix::CalcInfiniteFrustum(float left, float right, float bottom, float top, float zNear)
00118 {
00119     Identity();
00120     
00121     El(0,0) = (2*zNear) / (right - left);
00122     El(0,2) = (right + left) / (right - left);
00123     
00124     El(1,1) = (2*zNear) / (top - bottom);
00125     El(1,2) = (top + bottom) / (top - bottom);
00126     
00127     // nudge infinity in just slightly for lsb slop
00128     const float nudge = 1 - 1.0 / (1<<23);
00129 
00130     El(2,2) = -1  * nudge;
00131     El(2,3) = -2*zNear * nudge;
00132     
00133     El(3,2) = -1;
00134     El(3,3) = 0;
00135 }
00136 
00137 void Matrix::CalcSpotLight(const Matrix &lightWorldTransform, float fov, float width, float height, float zNear)
00138 {
00139     Matrix scale, proj, space;
00140     Vector3f halfVector(0.5f, 0.5f, 0.5f);
00141 
00142     Identity ();
00143     Translation (halfVector);
00144 
00145     scale.Identity ();
00146     scale.Scale (halfVector);
00147 
00148     // create projection matrix
00149     proj.CalcInfiniteProjection(width, height, fov, zNear);
00150 
00151     space = lightWorldTransform;
00152     space.InvertRotationMatrix();
00153 
00154     // so, we transform first into light space, then project, then scale and
00155     // translate (this)
00156     *this *= scale * proj * space;
00157 }
00158 
00159 bool Matrix::IsEqual(const Matrix& matrix) const
00160 {
00161     for (int i=0; i<16; ++i)
00162         if (matrix.m[i] != m[i]) return false;
00163 
00164     return true;
00165 }

Generated on Thu Apr 6 15:25:38 2006 for rcssserver3d by  doxygen 1.4.4