MercurySprite.cpp

Go to the documentation of this file.
00001 #include "MercuryDisplay.h"
00002 #include "MercurySprite.h"
00003 #include "MercuryUtil.h"
00004 #include "MercuryLog.h"
00005 #include "MercuryPoly.h"
00006 #include "MercuryTextureManager.h"
00007 #include "MercuryScreenManager.h"
00008 #include "MercuryObjectFactory.h"
00009 
00010 #define MC_TEXTURELOADED 0
00011 
00012 void MercurySprite::Init()
00013 {
00014     MercuryObject::Init();
00015 
00016     //Sprites draw from the center by default
00017     SetHAlignment(CENTER);
00018     SetVAlignment(VCENTER);
00019 
00020     m_origHeight = m_height = 1;
00021     m_origWidth = m_width = 1;
00022 
00023     m_material.m_diffuse.SetA(1.0f);
00024     m_material.m_diffuse.SetB(1.0f);
00025     m_material.m_diffuse.SetG(1.0f);
00026     m_material.m_diffuse.SetR(1.0f);
00027     SetMaterial(&m_material);
00028 
00029     MercuryNormal normal;
00030     normal.SetZ(-1);
00031     normal.SetX(0);
00032     normal.SetY(0);
00033 
00034     m_mesh.SetName("GenericSpriteMesh");
00035     MESHMAN.RegMesh( &m_mesh, "SpriteDummy", false );
00036     m_mesh.SetNumVertices(4);
00037 
00038     //Upper left
00039     m_mesh[0].SetNormal(normal);
00040 
00041     //Lower left
00042     m_mesh[1].SetY(1);
00043     m_mesh[1].SetNormal(normal);
00044 
00045     //Lower Right
00046     m_mesh[2].SetX(1);
00047     m_mesh[2].SetY(1);
00048     m_mesh[2].SetNormal(normal);
00049 
00050     //Upper right
00051     m_mesh[3].SetX(1);
00052     m_mesh[3].SetNormal(normal);
00053 
00054     m_mesh.GetVertex(1)->SetV(1);
00055     m_mesh.GetVertex(2)->SetU(1);
00056     m_mesh.GetVertex(3)->SetU(1);
00057     m_mesh.GetVertex(2)->SetV(1);
00058 
00059     m_mesh.SetMaterial(&m_material);
00060     m_drawable = true;
00061 
00062     m_state = LOADED;
00063 
00064     m_glState.Disable(MGLS_ALL);
00065     m_glState.Enable(MGLS_DEPTHWRITE | MGLS_DEPTHTEST | MGLS_COLORWRITE | MGLS_BLEND | MGLS_TEXTURING | MGLS_OPAQUE);
00066 }
00067 
00068 void MercurySprite::Message( int Message, PStack & data, const MString & name )
00069 {
00070     switch ( Message ) 
00071     {
00072     case MC_TEXTURELOADED:
00073         {
00074             const MercuryTexture* t = (const MercuryTexture*)data.PeekItem(0).GetValueV();
00075             const ImageAttrs* imageAttrs = (const ImageAttrs*)data.PeekItem(1).GetValueV();
00076             const MercuryTexture *tt = m_material.GetTexture(0);
00077             if(tt == t)
00078             {
00079                 SetImageAttrs(*imageAttrs);
00080                 m_state = LOADED;
00081                 MercuryMessageHandler::UnregisterMessage( MC_TEXTURELOADED, "GetTextureID" );
00082             }
00083         }
00084         break;
00085     }
00086 }
00087 
00088 bool MercurySprite::Command( PStack & ret, const char * command, PStack & args )
00089 {
00090     if ( strcmp( command, "LoadImage" ) == 0 )
00091     {
00092         MString Parameter = args.PopItem().GetValueS();
00093         while( args.GetSize() )
00094             Parameter = Parameter + "," + args.PopItem().GetValueS();
00095         LoadImage( Parameter );
00096         return true;
00097     }
00098     return MercuryObject::Command( ret, command, args );
00099 }
00100 
00101 void MercurySprite::EnumerateCommands( MVector< MString > & toAdd )
00102 {
00103     toAdd.push_back( "LoadImage" );
00104     MercuryObject::EnumerateCommands( toAdd );
00105 }
00106 
00107 void MercurySprite::LoadImage(MString path)
00108 {
00109     if ( path.substr( 0,5 ) == "QUAD:" )
00110     {
00111         float ReadOut[6];
00112         int i = 5, j = 0;
00113         MString cl = "";
00114         while ( (unsigned)i < path.length() )
00115         {
00116             if ( path.substr( i, 1 ) == "," )
00117             {
00118                 ReadOut[j] = float( atof( cl.c_str() ) );
00119                 cl = "";
00120                 j++;
00121             } else 
00122                 cl += path.substr( i, 1 );
00123             i++;
00124         }
00125         ReadOut[j] = float( atof( cl.c_str() ) );
00126 
00127         m_material.ClearTextures();
00128         SetHeight(int(ReadOut[1]));
00129         SetWidth(int(ReadOut[0]));
00130         
00131         m_material.m_diffuse.SetR( ReadOut[2] );
00132         m_material.m_diffuse.SetG( ReadOut[3] );
00133         m_material.m_diffuse.SetB( ReadOut[4] );
00134         m_material.m_diffuse.SetA( ReadOut[5] );
00135 
00136         CalculateRealColor();
00137     } else
00138     {
00139         m_state = UNLOADED;
00140         //eves drop on texture loading
00141         m_material.ClearTextures();
00142         m_material.AddTexture( MercuryTextureManager::CreateTexture(path) );
00143         //eves drop on texture loading
00144         MercuryMessageHandler::RegisterMessage( MC_TEXTURELOADED, "GetTextureID" );
00145     }
00146 }
00147 
00148 void MercurySprite::LoadMaterial(const MercuryMaterial& material)
00149 {
00150     m_material = material;
00151     if (m_material.NumTextures() > 0)
00152     {
00153         SetHeight(m_material.GetTexture( 0 )->GetHeight() );
00154         SetWidth(m_material.GetTexture( 0 )->GetWidth() );
00155     }
00156 }
00157 
00158 void MercurySprite::MakeOrthoLine( const MercuryPoint &from, const MercuryPoint &to, float fWidth )
00159 {
00160     MercuryPoint vec = (to-from);
00161     
00162     SetWidth( (int)vec.Magnitude() );
00163     SetHeight( (int)fWidth );
00164     SetRotZ( ATAN2( vec.y, vec.x ) * 180 / 3.14159f );
00165     SetPosition( from + vec * .5 );
00166 }
00167 
00168 void MercurySprite::SetImageAttrs(const ImageAttrs& attrs)
00169 {
00170     SetHeight(attrs.m_height_original);
00171     SetWidth(attrs.m_width_original);
00172 }
00173 
00174 void MercurySprite::Draw() 
00175 {
00176     ASSERT(!GetName().empty());
00177     DISPLAY->SendMatrixData(GetFinalMatrix());
00178     DISPLAY->DrawSprite(m_mesh);
00179 }
00180 
00181 void MercurySprite::CalculateMatrices()
00182 {
00183     if ( m_taintedMatrix || (m_rotMode == RM_BILLBOARD) )
00184     {
00185         m_localMatrix.Identity();
00186 
00187         MercuryPoint scale = m_scale;
00188         scale.x *= m_origWidth;
00189         scale.y *= m_origHeight;
00190         
00191         if( m_rotMode == RM_NORMAL )
00192         {
00193             m_localMatrix.Transotale( m_position.x, m_position.y, m_position.z,
00194                                         m_rotation.x, m_rotation.y, m_rotation.z,
00195                                         scale.x, scale.y, scale.z );
00196 
00197             //this must be done after scaling
00198             if ((m_xalign != 0) || (m_yalign != 0))
00199                 m_localMatrix.Translate(m_xalign, m_yalign, 0);
00200             m_taintedMatrix = false;
00201         }
00202         else
00203         {
00204 
00205             m_localMatrix.Translate(m_position.x, m_position.y, m_position.z);
00206 
00207             switch ( m_rotMode )
00208             {
00209             case RM_OFF:
00210                 break;
00211             case RM_BILLBOARD:
00212                 {
00213                     MercuryPoint up(0,0,1);
00214                     static MercuryPoint directionProj;
00215                     static float angle;
00216                     static MercuryPoint axis;
00217                     static MercuryMatrix world;
00218 
00219                     //http://www.lighthouse3d.com/opengl/billboarding/index.php?billCyl
00220                     MercuryPoint gp(GetGlobalPosition());
00221                     MercuryPoint lcp;
00222 
00223                     MercuryScreen* screen = SCREENMAN->GetCurrentScreen();
00224                     if (screen)
00225                     {
00226                         MercuryCamera* camera = screen->GetCamera();
00227                         if (camera)
00228                         {
00229                             lcp = camera->GetPosition();
00230 //                          up = camera->GetUp();
00231                         }   
00232                     }
00233 
00234                     directionProj = GetGlobalPosition() - lcp;
00235                     directionProj.NormalizeSelf();
00236 
00237                     axis = up.CrossProduct(directionProj);
00238                     angle = ACOS(DotProduct(up, directionProj));
00239 
00240                     //The destroys the previous matrix
00241                     world.RotateAngAxis(angle*RADDEG, axis.x, axis.y, axis.z);
00242                     m_localMatrix *= world;
00243                 }
00244                 break;
00245             case RM_MATRIX:
00246                 m_localMatrix *= m_matrix;
00247                 break;
00248             case RM_QUATERNION:
00249                 {
00250                     MercuryMatrix m;
00251                     m_rotQuat.toMatrix4(m);
00252                     m_localMatrix *= m;
00253                 }
00254                 break;
00255             default:
00256                 break;
00257             };
00258 
00259             m_localMatrix.Scale(scale.x, scale.y, scale.z);
00260             if ((m_xalign != 0) || (m_yalign != 0))
00261                 m_localMatrix.Translate(m_xalign, m_yalign, 0);
00262             m_taintedMatrix = false;
00263         }
00264     }
00265 
00266     m_finalMatrix = WorldStack.GetTop() *= m_localMatrix;
00267 }
00268 
00269 REGISTER_OBJECT_TYPE( MercurySprite );
00270 
00271 /* 
00272  * Copyright (c) 2005-2006, Joshua Allen
00273  * All rights reserved.
00274  *
00275  * Redistribution and use in source and binary forms, with or
00276  * without modification, are permitted provided that the following
00277  * conditions are met:
00278  *  -   Redistributions of source code must retain the above
00279  *      copyright notice, this list of conditions and the following disclaimer.
00280  *  -   Redistributions in binary form must reproduce the above copyright
00281  *      notice, this list of conditions and the following disclaimer in
00282  *      the documentation and/or other materials provided with the distribution.
00283  *  -   Neither the name of the Mercury Engine nor the names of its
00284  *      contributors may be used to endorse or promote products derived from
00285  *      this software without specific prior written permission.
00286  *
00287  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00288  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00289  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00290  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
00291  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00292  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00293  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00294  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00295  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00296  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00297  */
00298 

Hosted by SourceForge.net Logo