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
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
00039 m_mesh[0].SetNormal(normal);
00040
00041
00042 m_mesh[1].SetY(1);
00043 m_mesh[1].SetNormal(normal);
00044
00045
00046 m_mesh[2].SetX(1);
00047 m_mesh[2].SetY(1);
00048 m_mesh[2].SetNormal(normal);
00049
00050
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
00141 m_material.ClearTextures();
00142 m_material.AddTexture( MercuryTextureManager::CreateTexture(path) );
00143
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
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
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
00231 }
00232 }
00233
00234 directionProj = GetGlobalPosition() - lcp;
00235 directionProj.NormalizeSelf();
00236
00237 axis = up.CrossProduct(directionProj);
00238 angle = ACOS(DotProduct(up, directionProj));
00239
00240
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
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298