D:/Zythum/DinoKod/Landscape/SubTileDraw.cpp

00001 //---------------------------------------------------------------------------------------------
00002 //      This file is a part of "DinoKod".
00003 //      Copyright © 2003 Dino Productions. All Rights Reserved.
00004 //      
00005 //      File                    : SubTileDraw.cpp
00006 //      Author                  : Sebastien LEIX        sebastien.leix@wanadoo.fr
00007 //      Date                    : 12/02/2003
00008 //      Modification    :
00009 //
00010 //---------------------------------------------------------------------------------------------
00011 #include "Common/Math3D.h"
00012 #include "Common/Directory.h"
00013 #include "Common/Game.h"
00014 #include "Common/Ini.h"
00015 #include "Render/Render.h"
00016 #include "Landscape/TileDraw.h"
00017 #include "Landscape/LandscapeDraw.h"
00018 #include "Landscape/SubTileDraw.h"
00019 
00020 //---------------------------------------------------------------------------------------------
00021 void KSubTileDrawMipMesh::ComputeNormal()
00022 {
00023         u32                     vtx;
00024         KVector         v0, v1, v2, Normal;
00025         float*          pnTri;
00026 
00027         pnTri = new float[m_nVertex];
00028 
00029         // Met a 0 toutes les normales
00030         for( vtx = 0; vtx < m_nVertex; vtx ++ )
00031         {
00032                 m_pVertex[vtx].Normal.x = 0.0f;
00033                 m_pVertex[vtx].Normal.y = 0.0f;
00034                 m_pVertex[vtx].Normal.z = 0.0f;
00035                 pnTri[vtx] = 0.0f;
00036         }
00037 
00038         // Calcul les normales en faisant la moyenne de des normales des faces qui partagent le vertex
00039         for( u32 mi = 0; mi < KSTMI_COUNT; mi ++ )
00040         {
00041                 for( u32 idx = 0; idx < m_nIndex[mi]; idx += 3 )
00042                 {
00043                         v0 = m_pVertex[ m_pIndex[mi][idx + 0] ].Position;
00044                         v1 = m_pVertex[ m_pIndex[mi][idx + 1] ].Position;
00045                         v2 = m_pVertex[ m_pIndex[mi][idx + 2] ].Position;
00046 
00047                         Normal = KVector::CrossProduct( v2 - v0, v1 - v0 );
00048                         
00049                         m_pVertex[ m_pIndex[mi][idx + 0] ].Normal += Normal;
00050                         m_pVertex[ m_pIndex[mi][idx + 1] ].Normal += Normal;
00051                         m_pVertex[ m_pIndex[mi][idx + 2] ].Normal += Normal;
00052                         
00053                         pnTri[m_pIndex[mi][idx + 0] ] += 1.0f;
00054                         pnTri[m_pIndex[mi][idx + 1] ] += 1.0f;
00055                         pnTri[m_pIndex[mi][idx + 2] ] += 1.0f;
00056                 }
00057         }
00058 
00059         // Fait la moyenne et normalise
00060         for( vtx = 0; vtx < m_nVertex; vtx ++ )
00061         {
00062                 m_pVertex[vtx].Normal /= pnTri[vtx];
00063                 m_pVertex[vtx].Normal.Normalize();
00064         }
00065 
00066         Deletev( pnTri );
00067 }
00068 
00069 //---------------------------------------------------------------------------------------------
00070 //---------------------------------------------------------------------------------------------
00071 //---------------------------------------------------------------------------------------------
00072 KSubTileDraw::KSubTileDraw( KTile* pTile, float PosX, float PosY )
00073 : KSubTile( pTile, PosX, PosY )
00074 {
00075         m_pMipMesh                      = NULL;
00076         m_CurrentMipLevel       = 0;
00077         m_bDraw                         = false;
00078         m_pIndexList            = NULL;
00079         m_nIndexList            = 0;
00080         m_nIndexListPos         = 0;
00081         m_hShader                       = KSHADER_NO;   
00082         m_pShader                       = NULL;
00083 
00084 //      char    pTex[1024];
00085 //      sprintf( pTex, "Maps\\%s\\Tile%ix%i\\SubTile%ix%i", pTileDraw->GetpDirectory(), (int)(pTileDraw->GetPosX() / TILE_SIZE_X), (int)(pTileDraw->GetPosY() / TILE_SIZE_Y), (int)(PosX / TILE_SUBTILE_SIZE_X), (int)(PosY / TILE_SUBTILE_SIZE_Y) );
00086 //      m_hTestShader           = GetpTileDraw()->GetpRender()->GetpShaderBank()->LoadShader( "textures/grass" );
00087 //      m_hTestShader           = GetpTileDraw()->GetpRender()->GetpShaderBank()->LoadShader( pTex );
00088 
00089         u32             SizeX = TILE_NCELLS_X/TILE_NSUBTILES_X;
00090         u32             SizeY = TILE_NCELLS_Y/TILE_NSUBTILES_Y;
00091 
00092         // Calcul le nombre de niveau de mipmesh
00093         KASSERT( TILE_NSUBTILES_X == TILE_NSUBTILES_Y );
00094 
00095 //      u32 n = 1;
00096         m_nMipMesh = GetnMipMeshLevels();
00097 /*      while( n < (TILE_SUBTILE_SIZE_X / TILE_CELL_SIZE_X) )
00098         {
00099                 n *= 2;
00100                 m_nMipMesh ++;
00101         }*/
00102 //      m_nMipMesh -= 2;
00103 
00104         u32     MipValue;
00105 
00106         // Creation des niveaux de mipmesh
00107         m_pMipMesh = new KSubTileDrawMipMesh[ m_nMipMesh ];
00108         for( u32 m = 0; m < m_nMipMesh; m ++ )
00109         {
00110                 MipValue = (u32)powf( 2, (float)m );
00111                 //
00112                 //      Vertex
00113                 //
00114 //              u32     v = 0;
00115 //              s32     hvx, hvy;
00116 
00117                 m_pMipMesh[m].m_nVertex = ((SizeX + 1) * (SizeY + 1)) / MipValue;
00118                 m_pMipMesh[m].m_pVertex = new KVertex2[ m_pMipMesh[m].m_nVertex ];
00119 
00120                 // La construction des vertex est faite d'un seul coup plus tard.
00121 
00122 /*              for( u32 vy = 0; vy < SizeY + 1; vy += MipValue )
00123                 {
00124                         for( u32 vx = 0; vx < SizeX + 1; vx += MipValue )
00125                         {
00126                                 hvx = (s32)(m_PosX / TILE_CELL_SIZE_X) + (s32)vx;
00127                                 hvy = (s32)(m_PosY / TILE_CELL_SIZE_Y) + (s32)vy;
00128 
00129                                 // TODO : liaison entre tiles
00130                                 if( hvx >= TILE_NCELLS_X ) hvx = TILE_NCELLS_X - 1;
00131                                 if( hvy >= TILE_NCELLS_Y ) hvy = TILE_NCELLS_Y - 1;
00132 
00133                                 m_pMipMesh[m].m_pVertex[v].Position     = KVector( (float)m_PosX + vx * TILE_CELL_SIZE_X, (float)m_PosY + vy * TILE_CELL_SIZE_Y, GetpTileDraw()->GetHeight( hvx, hvy ) );
00134                                 
00135                                 float r = ((float)rand() / (float)RAND_MAX);
00136                                 float g = ((float)rand() / (float)RAND_MAX);
00137                                 float b = ((float)rand() / (float)RAND_MAX);
00138                                 
00139                                 u8 rr = 200 + (u8)(50.0f * r);
00140                                 u8 gg = 200 + (u8)(50.0f * g);
00141                                 u8 bb = 200 + (u8)(50.0f * b);
00142 
00143                                 m_pMipMesh[m].m_pVertex[v].Color        = KRGB( rr, gg ,bb );//KRGB( 255, 255, 255 );
00144                                 m_pMipMesh[m].m_pVertex[v].Specular     = KRGB( 0, 0, 0 );
00145                                 m_pMipMesh[m].m_pVertex[v].tu           = (float)vx;//(((vx / MipValue) % 2) * MipValue);
00146                                 m_pMipMesh[m].m_pVertex[v].tv           = (float)vy;//(((vy / MipValue) % 2) * MipValue);
00147                                 v ++;
00148                         }
00149                 }
00150 */
00151                 //
00152                 //      Index
00153                 //
00154                 u32     idx;
00155                 u32 ix, iy;
00156                 u32     i;
00157 
00158                 u32 IndexSizeX = SizeX / MipValue;
00159                 u32 IndexSizeY = SizeY / MipValue;
00160 
00161                 //
00162                 //      Center
00163                 //
00164                 if( ( IndexSizeX > 2 ) && ( IndexSizeY > 2 ) )
00165                 {
00166                         m_pMipMesh[m].m_nIndex[KSTMI_CENTER] = (IndexSizeX - 2) * (IndexSizeY - 2) * 6;
00167                         m_pMipMesh[m].m_pIndex[KSTMI_CENTER] = new KINDEX[ m_pMipMesh[m].m_nIndex[KSTMI_CENTER] ];
00168 
00169                         i = 0;
00170                         for( iy = 1; iy < IndexSizeY - 1; iy ++  )
00171                         {
00172                                 for( ix = 1; ix < IndexSizeX - 1; ix ++ )
00173                                 {
00174                                         idx = (iy * (IndexSizeX + 1) + ix);
00175 
00176                                         // Triangle 1
00177                                         m_pMipMesh[m].m_pIndex[KSTMI_CENTER][i + 0] = (KINDEX)(idx);
00178                                         m_pMipMesh[m].m_pIndex[KSTMI_CENTER][i + 1] = (KINDEX)(idx + IndexSizeX + 1);
00179                                         m_pMipMesh[m].m_pIndex[KSTMI_CENTER][i + 2] = (KINDEX)(idx + 1);
00180 
00181                                         // Triangle 2
00182                                         m_pMipMesh[m].m_pIndex[KSTMI_CENTER][i + 3] = (KINDEX)(idx + 1);
00183                                         m_pMipMesh[m].m_pIndex[KSTMI_CENTER][i + 4] = (KINDEX)(idx + IndexSizeX + 1);
00184                                         m_pMipMesh[m].m_pIndex[KSTMI_CENTER][i + 5] = (KINDEX)(idx + IndexSizeX + 2);
00185                                         i += 6;
00186                                 }
00187                         }
00188                         KASSERT( i == m_pMipMesh[m].m_nIndex[KSTMI_CENTER] );
00189                 }
00190         
00191                 //
00192                 //      Center niveau mipmesh le plus eleve 1x1
00193                 //
00194                 if( ( IndexSizeX == 1 ) && ( IndexSizeY == 1 ) )
00195                 {
00196                         m_pMipMesh[m].m_nIndex[KSTMI_CENTER] = 6;
00197                         m_pMipMesh[m].m_pIndex[KSTMI_CENTER] = new KINDEX[ m_pMipMesh[m].m_nIndex[KSTMI_CENTER] ];
00198 
00199                         i = 0;
00200 
00201                         // Triangle 1
00202                         m_pMipMesh[m].m_pIndex[KSTMI_CENTER][i + 0] = (KINDEX)0;
00203                         m_pMipMesh[m].m_pIndex[KSTMI_CENTER][i + 1] = (KINDEX)2;
00204                         m_pMipMesh[m].m_pIndex[KSTMI_CENTER][i + 2] = (KINDEX)3;
00205 
00206                         // Triangle 2
00207                         m_pMipMesh[m].m_pIndex[KSTMI_CENTER][i + 3] = (KINDEX)0;
00208                         m_pMipMesh[m].m_pIndex[KSTMI_CENTER][i + 4] = (KINDEX)3;
00209                         m_pMipMesh[m].m_pIndex[KSTMI_CENTER][i + 5] = (KINDEX)1;
00210 
00211                         i += 6;
00212 
00213                         KASSERT( i == m_pMipMesh[m].m_nIndex[KSTMI_CENTER] );
00214                 }
00215 
00216                 //
00217                 // Up
00218                 //
00219                 if( IndexSizeX > 1 )
00220                 {
00221                         // nombre de triangle dans la bande : (IndexSizeX - 2) * 2
00222                         // nombre de triangle sur les coté      : 2
00223                         m_pMipMesh[m].m_nIndex[KSTMI_UP] = ((IndexSizeX - 2) * 2 + 2) * 3;
00224                         m_pMipMesh[m].m_pIndex[KSTMI_UP] = new KINDEX[ m_pMipMesh[m].m_nIndex[KSTMI_UP] ];
00225 
00226                         i = 0;
00227 
00228                         // Triangle coté gauche
00229                         m_pMipMesh[m].m_pIndex[KSTMI_UP][i + 0] = (KINDEX)(IndexSizeX * (IndexSizeX + 1));
00230                         m_pMipMesh[m].m_pIndex[KSTMI_UP][i + 1] = (KINDEX)(IndexSizeX * (IndexSizeX + 1) + 1);
00231                         m_pMipMesh[m].m_pIndex[KSTMI_UP][i + 2] = (KINDEX)(IndexSizeX * IndexSizeX);
00232                                                                                                                                 
00233                         // Triangle coté droit                                                          
00234                         m_pMipMesh[m].m_pIndex[KSTMI_UP][i + 3] = (KINDEX)((IndexSizeX + 1) * (IndexSizeX + 1) - 2);
00235                         m_pMipMesh[m].m_pIndex[KSTMI_UP][i + 4] = (KINDEX)((IndexSizeX + 1) * (IndexSizeX + 1) - 1);
00236                         m_pMipMesh[m].m_pIndex[KSTMI_UP][i + 5] = (KINDEX)((IndexSizeX) * (IndexSizeX + 1) - 2);
00237 
00238                         i += 6;
00239 
00240                         // Bande
00241                         for( ix = 1; ix < IndexSizeX - 1; ix += 1 )
00242                         {
00243                                 idx = (IndexSizeY - 1) * (IndexSizeX + 1) + ix;
00244 
00245                                 // Triangle 1
00246                                 m_pMipMesh[m].m_pIndex[KSTMI_UP][i + 0] = (KINDEX)(idx);
00247                                 m_pMipMesh[m].m_pIndex[KSTMI_UP][i + 1] = (KINDEX)(idx + IndexSizeX + 1);
00248                                 m_pMipMesh[m].m_pIndex[KSTMI_UP][i + 2] = (KINDEX)(idx + 1);
00249                                                                                                                                         
00250                                 // Triangle 2                                                                           
00251                                 m_pMipMesh[m].m_pIndex[KSTMI_UP][i + 3] = (KINDEX)(idx + 1);
00252                                 m_pMipMesh[m].m_pIndex[KSTMI_UP][i + 4] = (KINDEX)(idx + IndexSizeX + 1);
00253                                 m_pMipMesh[m].m_pIndex[KSTMI_UP][i + 5] = (KINDEX)(idx + IndexSizeX + 2);
00254         
00255                                 i += 6;
00256                         }
00257 
00258                         KASSERT( i == m_pMipMesh[m].m_nIndex[KSTMI_UP] );
00259                 }
00260 
00261                 //
00262                 //      Mip Up
00263                 //
00264                 if( IndexSizeX > 1 )
00265                 {
00266                         // nombre de triangle dans la bande haute       : (IndexSizeX / 2)
00267                         // nombre de triangle dans la bande basse       : (IndexSizeX - 2)
00268                         m_pMipMesh[m].m_nIndex[KSTMI_MIP_UP] = (IndexSizeX / 2) * 3 + (IndexSizeX - 2) * 3;
00269                         m_pMipMesh[m].m_pIndex[KSTMI_MIP_UP] = new KINDEX[ m_pMipMesh[m].m_nIndex[KSTMI_MIP_UP] ];
00270                         
00271                         i = 0;
00272 
00273                         // Bande Haute
00274                         for( ix = 0; ix < IndexSizeX; ix += 2 )
00275                         {
00276                                 idx = ix + (IndexSizeX + 1) * IndexSizeY;
00277 
00278                                 // Triangle 1
00279                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_UP][i + 0] = (KINDEX)(idx);
00280                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_UP][i + 1] = (KINDEX)(idx + 2);
00281                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_UP][i + 2] = (KINDEX)(idx - IndexSizeX);
00282         
00283                                 i += 3;
00284                         }
00285                         // Bande Basse
00286                         for( ix = 1; ix < IndexSizeX - 1; ix += 2 )
00287                         {
00288                                 idx = ix + (IndexSizeX + 1) * IndexSizeY;
00289 
00290                                 // Triangle 1
00291                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_UP][i + 0] = (KINDEX)(idx - IndexSizeX - 1);
00292                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_UP][i + 1] = (KINDEX)(idx + 1);
00293                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_UP][i + 2] = (KINDEX)(idx - IndexSizeX);
00294         
00295                                 // Triangle 2
00296                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_UP][i + 3] = (KINDEX)(idx - IndexSizeX);
00297                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_UP][i + 4] = (KINDEX)(idx + 1);
00298                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_UP][i + 5] = (KINDEX)(idx - IndexSizeX + 1);
00299         
00300                                 i += 6;
00301                         }
00302 
00303                         KASSERT( i == m_pMipMesh[m].m_nIndex[KSTMI_MIP_UP] );
00304                 }
00305 
00306                 //
00307                 //      Down
00308                 //
00309                 if( IndexSizeX > 1 )
00310                 {
00311                         // nombre de triangle dans la bande : (IndexSizeX - 2) * 2
00312                         // nombre de triangle sur les coté      : 2
00313                         m_pMipMesh[m].m_nIndex[KSTMI_DOWN] = ((IndexSizeX - 2) * 2 + 2) * 3;
00314                         m_pMipMesh[m].m_pIndex[KSTMI_DOWN] = new KINDEX[ m_pMipMesh[m].m_nIndex[KSTMI_DOWN] ];
00315 
00316                         i = 0;
00317 
00318                         // Triangle coté gauche
00319                         m_pMipMesh[m].m_pIndex[KSTMI_DOWN][i + 0] = (KINDEX)(0);
00320                         m_pMipMesh[m].m_pIndex[KSTMI_DOWN][i + 1] = (KINDEX)(IndexSizeX + 2);
00321                         m_pMipMesh[m].m_pIndex[KSTMI_DOWN][i + 2] = (KINDEX)(1);
00322                                                                                                                                 
00323                         // Triangle coté droit                                                          
00324                         m_pMipMesh[m].m_pIndex[KSTMI_DOWN][i + 3] = (KINDEX)(IndexSizeX - 1);
00325                         m_pMipMesh[m].m_pIndex[KSTMI_DOWN][i + 4] = (KINDEX)(IndexSizeX + IndexSizeX);
00326                         m_pMipMesh[m].m_pIndex[KSTMI_DOWN][i + 5] = (KINDEX)(IndexSizeX);
00327 
00328                         i += 6;
00329 
00330                         // Bande
00331                         for( ix = 1; ix < IndexSizeX - 1; ix += 1 )
00332                         {
00333                                 idx = ix;
00334 
00335                                 // Triangle 1
00336                                 m_pMipMesh[m].m_pIndex[KSTMI_DOWN][i + 0] = (KINDEX)(idx);
00337                                 m_pMipMesh[m].m_pIndex[KSTMI_DOWN][i + 1] = (KINDEX)(idx + IndexSizeX + 1);
00338                                 m_pMipMesh[m].m_pIndex[KSTMI_DOWN][i + 2] = (KINDEX)(idx + 1);
00339                                                                                                                                         
00340                                 // Triangle 2                                                                           
00341                                 m_pMipMesh[m].m_pIndex[KSTMI_DOWN][i + 3] = (KINDEX)(idx + 1);
00342                                 m_pMipMesh[m].m_pIndex[KSTMI_DOWN][i + 4] = (KINDEX)(idx + IndexSizeX + 1);
00343                                 m_pMipMesh[m].m_pIndex[KSTMI_DOWN][i + 5] = (KINDEX)(idx + IndexSizeX + 2);
00344         
00345                                 i += 6;
00346                         }
00347 
00348                         KASSERT( i == m_pMipMesh[m].m_nIndex[KSTMI_DOWN] );
00349                 }
00350 
00351                 //
00352                 //      Mip Down
00353                 //
00354                 if( IndexSizeX > 1 )
00355                 {
00356                         // nombre de triangle dans la bande haute       : (IndexSizeX - 2)
00357                         // nombre de triangle dans la bande basse       : (IndexSizeX / 2)
00358                         m_pMipMesh[m].m_nIndex[KSTMI_MIP_DOWN] = (IndexSizeX / 2) * 3 + (IndexSizeX - 2) * 3;
00359                         m_pMipMesh[m].m_pIndex[KSTMI_MIP_DOWN] = new KINDEX[ m_pMipMesh[m].m_nIndex[KSTMI_MIP_DOWN] ];
00360                         
00361                         i = 0;
00362 
00363                         // Bande Basse
00364                         for( ix = 0; ix < IndexSizeX; ix += 2 )
00365                         {
00366                                 idx = ix;
00367 
00368                                 // Triangle 1
00369                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_DOWN][i + 0] = (KINDEX)(idx);
00370                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_DOWN][i + 1] = (KINDEX)(idx + IndexSizeX + 2);
00371                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_DOWN][i + 2] = (KINDEX)(idx + 2);
00372         
00373                                 i += 3;
00374                         }
00375                         // Bande Haute
00376                         for( ix = 1; ix < IndexSizeX - 1; ix += 2 )
00377                         {
00378                                 idx = ix;
00379 
00380                                 // Triangle 1
00381                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_DOWN][i + 0] = (KINDEX)(idx + 1);
00382                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_DOWN][i + 1] = (KINDEX)(idx + IndexSizeX + 1);
00383                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_DOWN][i + 2] = (KINDEX)(idx + IndexSizeX + 2);
00384         
00385                                 // Triangle 2
00386                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_DOWN][i + 3] = (KINDEX)(idx + 1);
00387                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_DOWN][i + 4] = (KINDEX)(idx + IndexSizeX + 2);
00388                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_DOWN][i + 5] = (KINDEX)(idx + IndexSizeX + 3);
00389         
00390                                 i += 6;
00391                         }
00392 
00393                         KASSERT( i == m_pMipMesh[m].m_nIndex[KSTMI_MIP_DOWN] );
00394                 }
00395 
00396                 //
00397                 // Left
00398                 //
00399                 if( IndexSizeY > 1 )
00400                 {
00401                         // nombre de triangle dans la bande : (IndexSizeY - 2) * 2
00402                         // nombre de triangle sur les coté      : 2
00403                         m_pMipMesh[m].m_nIndex[KSTMI_LEFT] = ((IndexSizeY - 2) * 2 + 2) * 3;
00404                         m_pMipMesh[m].m_pIndex[KSTMI_LEFT] = new KINDEX[ m_pMipMesh[m].m_nIndex[KSTMI_LEFT] ];
00405 
00406                         i = 0;
00407 
00408                         // Triangle coté gauche
00409                         m_pMipMesh[m].m_pIndex[KSTMI_LEFT][i + 0] = (KINDEX)(0);
00410                         m_pMipMesh[m].m_pIndex[KSTMI_LEFT][i + 1] = (KINDEX)(IndexSizeX + 1);
00411                         m_pMipMesh[m].m_pIndex[KSTMI_LEFT][i + 2] = (KINDEX)(IndexSizeX + 2);
00412                                                                                                                                 
00413                         // Triangle coté droit                                                          
00414                         m_pMipMesh[m].m_pIndex[KSTMI_LEFT][i + 3] = (KINDEX)(IndexSizeX * IndexSizeY - 1);
00415                         m_pMipMesh[m].m_pIndex[KSTMI_LEFT][i + 4] = (KINDEX)(IndexSizeX * (IndexSizeY + 1));
00416                         m_pMipMesh[m].m_pIndex[KSTMI_LEFT][i + 5] = (KINDEX)(IndexSizeX * IndexSizeY);
00417 
00418                         i += 6;
00419 
00420                         // Bande
00421                         for( iy = 1; iy < IndexSizeY - 1; iy += 1 )
00422                         {
00423                                 idx = iy * (IndexSizeX + 1);
00424 
00425                                 // Triangle 1
00426                                 m_pMipMesh[m].m_pIndex[KSTMI_LEFT][i + 0] = (KINDEX)(idx);
00427                                 m_pMipMesh[m].m_pIndex[KSTMI_LEFT][i + 1] = (KINDEX)(idx + IndexSizeY + 1);
00428                                 m_pMipMesh[m].m_pIndex[KSTMI_LEFT][i + 2] = (KINDEX)(idx + 1);
00429                                                                                                                                         
00430                                 // Triangle 2                                                                           
00431                                 m_pMipMesh[m].m_pIndex[KSTMI_LEFT][i + 3] = (KINDEX)(idx + 1);
00432                                 m_pMipMesh[m].m_pIndex[KSTMI_LEFT][i + 4] = (KINDEX)(idx + IndexSizeY + 1);
00433                                 m_pMipMesh[m].m_pIndex[KSTMI_LEFT][i + 5] = (KINDEX)(idx + IndexSizeY + 2);
00434         
00435                                 i += 6;
00436                         }
00437 
00438                         KASSERT( i == m_pMipMesh[m].m_nIndex[KSTMI_LEFT] );
00439                 }
00440 
00441                 //
00442                 //      Mip Left
00443                 //
00444                 if( IndexSizeY > 1 )
00445                 {
00446                         // nombre de triangle dans la bande haute       : (IndexSizeY / 2)
00447                         // nombre de triangle dans la bande basse       : (IndexSizeY - 2)
00448                         m_pMipMesh[m].m_nIndex[KSTMI_MIP_LEFT] = (IndexSizeY / 2) * 3 + (IndexSizeY - 2) * 3;
00449                         m_pMipMesh[m].m_pIndex[KSTMI_MIP_LEFT] = new KINDEX[ m_pMipMesh[m].m_nIndex[KSTMI_MIP_LEFT] ];
00450                         
00451                         i = 0;
00452 
00453                         // Bande Haute
00454                         for( iy = 0; iy < IndexSizeY; iy += 2 )
00455                         {
00456                                 idx = iy * (IndexSizeX + 1);
00457 
00458                                 // Triangle 1
00459                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_LEFT][i + 0] = (KINDEX)(idx);
00460                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_LEFT][i + 1] = (KINDEX)(idx + (IndexSizeX + 1) * 2);
00461                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_LEFT][i + 2] = (KINDEX)(idx + IndexSizeX + 2);
00462         
00463                                 i += 3;
00464                         }
00465                         // Bande Basse
00466                         for( iy = 1; iy < IndexSizeY - 1; iy += 2 )
00467                         {
00468                                 idx = iy * (IndexSizeX + 1);
00469 
00470                                 // Triangle 1
00471                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_LEFT][i + 0] = (KINDEX)(idx + 1);
00472                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_LEFT][i + 1] = (KINDEX)(idx + IndexSizeX + 1);
00473                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_LEFT][i + 2] = (KINDEX)(idx + IndexSizeX + 2);
00474         
00475                                 // Triangle 2
00476                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_LEFT][i + 3] = (KINDEX)(idx + IndexSizeX + 1);
00477                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_LEFT][i + 4] = (KINDEX)(idx + (IndexSizeX + 1 ) * 2 + 1);
00478                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_LEFT][i + 5] = (KINDEX)(idx + IndexSizeX + 2);
00479         
00480                                 i += 6;
00481                         }
00482 
00483                         KASSERT( i == m_pMipMesh[m].m_nIndex[KSTMI_MIP_LEFT] );
00484                 }
00485 
00486                 //
00487                 //      Right
00488                 //
00489                 if( IndexSizeY > 1 )
00490                 {
00491                         // nombre de triangle dans la bande : (IndexSizeY - 2) * 2
00492                         // nombre de triangle sur les coté      : 2
00493                         m_pMipMesh[m].m_nIndex[KSTMI_RIGHT] = ((IndexSizeY - 2) * 2 + 2) * 3;
00494                         m_pMipMesh[m].m_pIndex[KSTMI_RIGHT] = new KINDEX[ m_pMipMesh[m].m_nIndex[KSTMI_RIGHT] ];
00495 
00496                         i = 0;
00497 
00498                         // Triangle coté gauche
00499                         m_pMipMesh[m].m_pIndex[KSTMI_RIGHT][i + 0] = (KINDEX)(IndexSizeX);
00500                         m_pMipMesh[m].m_pIndex[KSTMI_RIGHT][i + 1] = (KINDEX)(IndexSizeX * 2);
00501                         m_pMipMesh[m].m_pIndex[KSTMI_RIGHT][i + 2] = (KINDEX)(IndexSizeX * 2 + 1);
00502                                                                                                                                  
00503                         // Triangle coté droit                                                           
00504                         m_pMipMesh[m].m_pIndex[KSTMI_RIGHT][i + 3] = (KINDEX)((IndexSizeX + 1) * IndexSizeY - 2);
00505                         m_pMipMesh[m].m_pIndex[KSTMI_RIGHT][i + 4] = (KINDEX)((IndexSizeX + 1) * (IndexSizeY + 1) - 1);
00506                         m_pMipMesh[m].m_pIndex[KSTMI_RIGHT][i + 5] = (KINDEX)((IndexSizeX + 1) * IndexSizeY - 1);
00507 
00508                         i += 6;
00509 
00510                         // Bande
00511                         for( iy = 1; iy < IndexSizeY - 1; iy += 1 )
00512                         {
00513                                 idx = iy * (IndexSizeX + 1) + IndexSizeX - 1;
00514 
00515                                 // Triangle 1
00516                                 m_pMipMesh[m].m_pIndex[KSTMI_RIGHT][i + 0] = (KINDEX)(idx);
00517                                 m_pMipMesh[m].m_pIndex[KSTMI_RIGHT][i + 1] = (KINDEX)(idx + IndexSizeY + 1);
00518                                 m_pMipMesh[m].m_pIndex[KSTMI_RIGHT][i + 2] = (KINDEX)(idx + 1);
00519                                                                                                                                           
00520                                 // Triangle 2                                                                             
00521                                 m_pMipMesh[m].m_pIndex[KSTMI_RIGHT][i + 3] = (KINDEX)(idx + 1);
00522                                 m_pMipMesh[m].m_pIndex[KSTMI_RIGHT][i + 4] = (KINDEX)(idx + IndexSizeY + 1);
00523                                 m_pMipMesh[m].m_pIndex[KSTMI_RIGHT][i + 5] = (KINDEX)(idx + IndexSizeY + 2);
00524         
00525                                 i += 6;
00526                         }
00527 
00528                         KASSERT( i == m_pMipMesh[m].m_nIndex[KSTMI_RIGHT] );
00529                 }
00530 
00531                 //
00532                 //      Mip Right
00533                 //
00534                 if( IndexSizeY > 1 )
00535                 {
00536                         // nombre de triangle dans la bande haute       : (IndexSizeY - 2)
00537                         // nombre de triangle dans la bande basse       : (IndexSizeY / 2)
00538                         m_pMipMesh[m].m_nIndex[KSTMI_MIP_RIGHT] = (IndexSizeY / 2) * 3 + (IndexSizeY - 2) * 3;
00539                         m_pMipMesh[m].m_pIndex[KSTMI_MIP_RIGHT] = new KINDEX[ m_pMipMesh[m].m_nIndex[KSTMI_MIP_RIGHT] ];
00540                         
00541                         i = 0;
00542 
00543                         // Bande Basse
00544                         for( iy = 0; iy < IndexSizeY; iy += 2 )
00545                         {
00546                                 idx = iy * (IndexSizeX + 1) + IndexSizeX;
00547 
00548                                 // Triangle 1
00549                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_RIGHT][i + 0] = (KINDEX)(idx);
00550                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_RIGHT][i + 1] = (KINDEX)(idx + IndexSizeX);
00551                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_RIGHT][i + 2] = (KINDEX)(idx + IndexSizeX * 2 + 2);
00552         
00553                                 i += 3;
00554                         }
00555                         // Bande Haute
00556                         for( iy = 1; iy < IndexSizeY - 1; iy += 2 )
00557                         {
00558                                 idx = iy * (IndexSizeX + 1) + IndexSizeX;
00559 
00560                                 // Triangle 1
00561                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_RIGHT][i + 0] = (KINDEX)(idx - 1);
00562                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_RIGHT][i + 1] = (KINDEX)(idx + IndexSizeX);
00563                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_RIGHT][i + 2] = (KINDEX)(idx + IndexSizeX + 1);
00564         
00565                                 // Triangle 2
00566                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_RIGHT][i + 3] = (KINDEX)(idx + IndexSizeX);
00567                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_RIGHT][i + 4] = (KINDEX)(idx + (IndexSizeX * 2) + 1);
00568                                 m_pMipMesh[m].m_pIndex[KSTMI_MIP_RIGHT][i + 5] = (KINDEX)(idx + IndexSizeX + 1);
00569         
00570                                 i += 6;
00571                         }
00572 
00573                         KASSERT( i == m_pMipMesh[m].m_nIndex[KSTMI_MIP_RIGHT] );
00574                 }
00575         }
00576 
00577         //
00578         //      Contruit les vertex a partir de la hauteur
00579         //
00580         BuildVertex();
00581 
00582         // Buffer qui recevra les indices pour la subtile entière
00583         m_nIndexList = 0;
00584         for( u32 mi = 0; mi < KSTMI_COUNT; mi ++ )
00585                 m_nIndexList += m_pMipMesh[0].m_nIndex[mi];
00586         m_pIndexList = new KINDEX[ m_nIndexList ];
00587 
00588         // Calcule la bounding box
00589         ComputeBBox();
00590 }
00591 
00592 //---------------------------------------------------------------------------------------------
00593 KSubTileDraw::~KSubTileDraw()
00594 {
00595         for( u32 m = 0; m < m_nMipMesh; m ++ )
00596         {
00597                 if( m_pMipMesh[m].m_pVertex )
00598                         Deletev( m_pMipMesh[m].m_pVertex );
00599 
00600                 if( m_pIndexList )
00601                         Deletev( m_pIndexList );
00602 
00603                 for( u32 i = 0; i < KSTMI_COUNT; i ++ )
00604                 {
00605                         if( m_pMipMesh[m].m_pIndex[i] )
00606                                 Deletev( m_pMipMesh[m].m_pIndex[i] );
00607                 }
00608         }
00609         Deletev( m_pMipMesh );
00610 }
00611 
00612 //---------------------------------------------------------------------------------------------
00613 bool KSubTileDraw::Init( KRender* pRender )
00614 {
00615 //      char    pTex[1024];
00616 //      sprintf( pTex, "Maps\\%s\\Tile%ix%i\\SubTile%ix%i", pTileDraw->GetpDirectory(), (int)(pTileDraw->GetPosX() / TILE_SIZE_X), (int)(pTileDraw->GetPosY() / TILE_SIZE_Y), (int)(PosX / TILE_SUBTILE_SIZE_X), (int)(PosY / TILE_SUBTILE_SIZE_Y) );
00617 //      m_hShader = GetpTileDraw()->GetpRender()->GetpShaderBank()->LoadShader( "textures/grass" );
00618 //      m_hTestShader           = GetpTileDraw()->GetpRender()->GetpShaderBank()->LoadShader( pTex );
00619         m_hShader = GetpTileDraw()->GetpRender()->GetpShaderBank()->CreateShader( "SubTile" );
00620         m_pShader = GetpTileDraw()->GetpRender()->GetpShaderBank()->GetpShader( m_hShader );
00621         
00622         ReloadShader();
00623 //      KShaderStage*   pStage = new KShaderStage();
00624 //      pStage->m_pMapName = strdup( "
00625 
00626         return true;
00627 }
00628 
00629 //---------------------------------------------------------------------------------------------
00630 void KSubTileDraw::ReloadShader()
00631 {
00632         m_pShader->FlushAllStages();
00633 
00634         if( m_pTextureName )
00635         {
00636 //              char    pTex[1024];
00637                 
00638 //              KStr sPath = g_Directory.GetPath( KStr( "Maps" ) );
00639 //              sprintf( pTex, "%sSubTiles/%s", (char*)sPath, m_pTextureName );
00640                 m_pShader->AddStage( m_pTextureName );
00641                 
00642 /*              sprintf( pTex, "%sSubTiles/Details", (char*)sPath );
00643                 m_pShader->AddStage( pTex, KRBLEND_ZERO, KRBLEND_SRC );
00644                 m_pShader->m_StageList[1]->m_TexCoordIndex = 1;*/
00645                 
00646                 u32             Size = g_pGame->GetpIniFile()->ReadInt( "LANDSCAPE", "TextureSize", 1 );
00647                 m_pShader->LoadTextures( Size );
00648         }
00649 }
00650 
00651 //---------------------------------------------------------------------------------------------
00652 void KSubTileDraw::BuildVertex()
00653 {
00654         u32             MipValue;
00655 //      s32             hvx, hvy;
00656         u32             vtx;
00657 
00658         u32             SizeX = TILE_NCELLS_X/TILE_NSUBTILES_X;
00659         u32             SizeY = TILE_NCELLS_Y/TILE_NSUBTILES_Y;
00660 
00661         s32             CellX = (s32)(GetpTileDraw()->GetPosX() + m_PosX) / TILE_CELL_SIZE_X;
00662         s32             CellY = (s32)(GetpTileDraw()->GetPosY() + m_PosY) / TILE_CELL_SIZE_Y;
00663 
00664         float   u, v;
00665         u32             Angle;
00666 
00667         KTILEHEIGHT             Height;
00668 
00669         for( u32 m = 0; m < m_nMipMesh; m ++ )
00670         {
00671                 // Calcule l'increment de mipmap
00672                 MipValue = (u32)powf( 2, (float)m );
00673 
00674                 vtx = 0;
00675                 for( u32 vy = 0; vy < SizeY + 1; vy += MipValue )
00676                 {
00677                         for( u32 vx = 0; vx < SizeX + 1; vx += MipValue )
00678                         {
00679 //                              hvx = (s32)(m_PosX / TILE_CELL_SIZE_X) + (s32)vx;
00680 //                              hvy = (s32)(m_PosY / TILE_CELL_SIZE_Y) + (s32)vy;
00681 
00682                                 // TODO : liaison entre tiles
00683 //                              if( hvx >= TILE_NCELLS_X ) hvx = TILE_NCELLS_X - 1;
00684 //                              if( hvy >= TILE_NCELLS_Y ) hvy = TILE_NCELLS_Y - 1;
00685 
00686                                 // Recupere la hauteur
00687                                 GetpTileDraw()->GetpLandscape()->GetCellHeight( CellX + vx, CellY + vy, &Height );
00688 
00689                                 m_pMipMesh[m].m_pVertex[vtx].Position   = KVector( (float)m_PosX + vx * TILE_CELL_SIZE_X, (float)m_PosY + vy * TILE_CELL_SIZE_Y, (float)Height );
00690                                 
00691                                 float r = ((float)rand() / (float)RAND_MAX);
00692                                 float g = ((float)rand() / (float)RAND_MAX);
00693                                 float b = ((float)rand() / (float)RAND_MAX);
00694                                 
00695                                 u8 rr = 200 + (u8)(50.0f * r);
00696                                 u8 gg = 200 + (u8)(50.0f * g);
00697                                 u8 bb = 200 + (u8)(50.0f * b);
00698 
00699 //                              m_pMipMesh[m].m_pVertex[vtx].Color      = KRGB( rr, gg ,bb );//KRGB( 255, 255, 255 );
00700 //                              m_pMipMesh[m].m_pVertex[vtx].Specular   = KRGB( 0, 0, 0 );
00701                                 m_pMipMesh[m].m_pVertex[vtx].Normal     = GetNormal( CellX + vx, CellY + vy );
00702 
00703 //                              m_pMipMesh[m].m_pVertex[vtx].tu         = (float)vx;//(((vx / MipValue) % 2) * MipValue);
00704 //                              m_pMipMesh[m].m_pVertex[vtx].tv         = (float)vy;//(((vy / MipValue) % 2) * MipValue);
00705                                 Angle = (u32)m_MapAngle / 90;
00706                                 Angle *= 90;
00707                                 Angle %= 360;
00708 
00709                                 switch( Angle )
00710                                 {
00711                                 case 0:
00712                                         u = (float)(vx / (float)SizeX);
00713                                         v = (float)(vy / (float)SizeY);
00714                                         break;
00715                                 case 90:
00716                                         u = (float)(vy / (float)SizeY);
00717                                         v = (float)(vx / (float)SizeX);
00718                                         break;
00719                                 case 180:
00720                                         u = 1.0f - (float)(vx / (float)SizeX);
00721                                         v = 1.0f - (float)(vy / (float)SizeY);
00722                                         break;
00723                                 case 270:
00724                                         u = 1.0f - (float)(vy / (float)SizeY);
00725                                         v = 1.0f - (float)(vx / (float)SizeX);
00726                                         break;
00727                                 }
00728 
00729                                 m_pMipMesh[m].m_pVertex[vtx].tu1        = u;//(float)(vx / (float)SizeX);
00730                                 m_pMipMesh[m].m_pVertex[vtx].tv1        = v;//(float)(vy / (float)SizeY);
00731                                 m_pMipMesh[m].m_pVertex[vtx].tu2        = (float)(vx);// / (float)SizeX);
00732                                 m_pMipMesh[m].m_pVertex[vtx].tv2        = (float)(vy);// / (float)SizeY);
00733                                 vtx ++;
00734                         }
00735                 }
00736 
00737                 // Calcul les normales
00738 //              m_pMipMesh[m].ComputeNormal();
00739         }
00740 }
00741 
00742 //---------------------------------------------------------------------------------------------
00743 KVector KSubTileDraw::GetNormal( s32 CellX, s32 CellY )
00744 {
00745         KTILEHEIGHT             h0, h1, h2, h3, h4, h5, h6;
00746         bool                    b0, b1, b2, b3, b4, b5, b6;
00747         KVector                 v0, v1, v2, v3, v4, v5, v6;
00748         KVector                 Normal( 0.0f, 0.0f, 0.0f );
00749         float                   n = 0;
00750 
00751         // Recupère les 5 hauteurs
00752         b0 = GetpTileDraw()->GetpLandscape()->GetCellHeight( CellX              , CellY         , &h0 );
00753         b1 = GetpTileDraw()->GetpLandscape()->GetCellHeight( CellX              , CellY + 1     , &h1 );
00754         b2 = GetpTileDraw()->GetpLandscape()->GetCellHeight( CellX + 1  , CellY         , &h2 );
00755         b3 = GetpTileDraw()->GetpLandscape()->GetCellHeight( CellX              , CellY - 1     , &h3 );
00756         b4 = GetpTileDraw()->GetpLandscape()->GetCellHeight( CellX - 1  , CellY         , &h4 );
00757         b5 = GetpTileDraw()->GetpLandscape()->GetCellHeight( CellX + 1  , CellY - 1     , &h5 );
00758         b6 = GetpTileDraw()->GetpLandscape()->GetCellHeight( CellX - 1  , CellY + 1     , &h6 );
00759 
00760         // Contruit les 5 points
00761         v0.x = 0.0f;
00762         v0.y = 0.0f;
00763         v0.z = (float)h0;
00764 
00765         v1.x = 0.0f;
00766         v1.y = TILE_CELL_SIZE_Y;
00767         v1.z = (float)h1;
00768 
00769         v2.x = TILE_CELL_SIZE_X;
00770         v2.y = 0.0f;
00771         v2.z = (float)h2;
00772 
00773         v3.x = 0.0f;
00774         v3.y = -TILE_CELL_SIZE_Y;
00775         v3.z = (float)h3;
00776 
00777         v4.x = -TILE_CELL_SIZE_X;
00778         v4.y = 0.0f;
00779         v4.z = (float)h4;
00780 
00781         v5.x = TILE_CELL_SIZE_X;
00782         v5.y = TILE_CELL_SIZE_Y;
00783         v5.z = (float)h5;
00784 
00785         v6.x = -TILE_CELL_SIZE_X;
00786         v6.y = -TILE_CELL_SIZE_Y;
00787         v6.z = (float)h6;
00788 
00789         // Calcule les 4 normales
00790         if( b1 && b2 )
00791         {
00792                 Normal += KVector::CrossProduct( v2 - v0, v1 - v0 );
00793                 n += 1.0f;
00794         }
00795 
00796         if( b2 && b3 )
00797         {
00798                 Normal += KVector::CrossProduct( v3 - v0, v2 - v0 );
00799                 n += 1.0f;
00800         }
00801 
00802         if( b3 && b4 )
00803         {
00804                 Normal += KVector::CrossProduct( v4 - v0, v3 - v0 );
00805                 n += 1.0f;
00806         }
00807 
00808         if( b4 && b1 )
00809         {
00810                 Normal += KVector::CrossProduct( v1 - v0, v4 - v0 );
00811                 n += 1.0f;
00812         }
00813 
00814 /*      // Calcule les 6 normales
00815         if( b1 && b2 )
00816         {
00817                 Normal += KVector::CrossProduct( v2 - v0, v1 - v0 );
00818                 n += 1.0f;
00819         }
00820 
00821         if( b2 && b5 )
00822         {
00823                 Normal += KVector::CrossProduct( v5 - v0, v2 - v0 );
00824                 n += 1.0f;
00825         }
00826 
00827         if( b5 && b3 )
00828         {
00829                 Normal += KVector::CrossProduct( v3 - v0, v5 - v0 );
00830                 n += 1.0f;
00831         }
00832 
00833         if( b3 && b4 )
00834         {
00835                 Normal += KVector::CrossProduct( v4 - v0, v3 - v0 );
00836                 n += 1.0f;
00837         }
00838 
00839         if( b4 && b6 )
00840         {
00841                 Normal += KVector::CrossProduct( v6 - v0, v4 - v0 );
00842                 n += 1.0f;
00843         }
00844 
00845         if( b6 && b1 )
00846         {
00847                 Normal += KVector::CrossProduct( v1 - v0, v6 - v0 );
00848                 n += 1.0f;
00849         }
00850 */
00851         if( n == 0.0f )
00852                 return KVector( 0.0f, 0.0f, 1.0f );
00853 
00854         // Fait la moyenne
00855         Normal /= n;
00856         Normal.Normalize();
00857 
00858         return Normal;
00859 }
00860 
00861 //---------------------------------------------------------------------------------------------
00862 bool KSubTileDraw::GetHeight( s32 CellX, s32 CellY, KTILEHEIGHT* pHeight )
00863 {
00864         // En dehors de la tile ?
00865         if( ( CellX < 0 ) || ( CellX >= TILE_NCELLS_X ) || ( CellY < 0 ) || ( CellY >= TILE_NCELLS_Y ) )
00866         {
00867                 *pHeight = 0;
00868                 return false;
00869         }
00870 
00871         *pHeight = GetpTileDraw()->GetHeight( CellX, CellY );
00872 
00873         return true;
00874 }
00875 
00876 
00877 //---------------------------------------------------------------------------------------------
00878 void KSubTileDraw::ComputeBBox()
00879 {
00880         KTILEHEIGHT             MinZ, MaxZ, h;
00881         u32                             SizeX, SizeY;
00882         u32                             CellPosX, CellPosY;
00883         float                   TilePosX, TilePosY;
00884 
00885         MinZ = MAX_TILEHEIGHT;
00886         MaxZ = MIN_TILEHEIGHT;
00887         
00888         SizeX           = TILE_NCELLS_X/TILE_NSUBTILES_X;
00889         SizeY           = TILE_NCELLS_Y/TILE_NSUBTILES_Y;
00890         CellPosX        = (u32)m_PosX / TILE_CELL_SIZE_X;
00891         CellPosY        = (u32)m_PosY / TILE_CELL_SIZE_Y;
00892 
00893         // Recherche le minimum et le maximum en Z
00894         for( u32 sty = 0; sty < SizeY; sty ++ )
00895         {
00896                 for( u32 stx = 0; stx < SizeX; stx ++ )
00897                 {
00898                         h = GetpTileDraw()->GetHeight( CellPosX + stx, CellPosY + sty );
00899                         
00900                         if( h < MinZ )
00901                                 MinZ = h;
00902 
00903                         if( h > MaxZ )
00904                                 MaxZ = h;
00905                 }
00906         }
00907 
00908         TilePosX        = GetpTileDraw()->GetPosX();
00909         TilePosY        = GetpTileDraw()->GetPosY();
00910 
00911         m_pBBox[0].x    = TilePosX + m_PosX;
00912         m_pBBox[0].y    = TilePosY + m_PosY;
00913         m_pBBox[0].z    = MinZ;
00914         m_pBBox[1].x    = TilePosX + m_PosX + SizeX * TILE_CELL_SIZE_X;
00915         m_pBBox[1].y    = TilePosY + m_PosY;
00916         m_pBBox[1].z    = MinZ;
00917         m_pBBox[2].x    = TilePosX + m_PosX;
00918         m_pBBox[2].y    = TilePosY + m_PosY + SizeY * TILE_CELL_SIZE_Y;
00919         m_pBBox[2].z    = MinZ;
00920         m_pBBox[3].x    = TilePosX + m_PosX + SizeX * TILE_CELL_SIZE_X;
00921         m_pBBox[3].y    = TilePosY + m_PosY + SizeY * TILE_CELL_SIZE_Y;
00922         m_pBBox[3].z    = MinZ;
00923 
00924         m_pBBox[4].x    = TilePosX + m_PosX;
00925         m_pBBox[4].y    = TilePosY + m_PosY;
00926         m_pBBox[4].z    = MaxZ;
00927         m_pBBox[5].x    = TilePosX + m_PosX + SizeX * TILE_CELL_SIZE_X;
00928         m_pBBox[5].y    = TilePosY + m_PosY;
00929         m_pBBox[5].z    = MaxZ;
00930         m_pBBox[6].x    = TilePosX + m_PosX;
00931         m_pBBox[6].y    = TilePosY + m_PosY + SizeY * TILE_CELL_SIZE_Y;
00932         m_pBBox[6].z    = MaxZ;
00933         m_pBBox[7].x    = TilePosX + m_PosX + SizeX * TILE_CELL_SIZE_X;
00934         m_pBBox[7].y    = TilePosY + m_PosY + SizeY * TILE_CELL_SIZE_Y;
00935         m_pBBox[7].z    = MaxZ;
00936 }
00937 
00938 //---------------------------------------------------------------------------------------------
00939 void KSubTileDraw::FlushIndexList()
00940 {
00941         m_nIndexListPos = 0;
00942 }
00943 
00944 //---------------------------------------------------------------------------------------------
00945 void KSubTileDraw::AddIndexList( u32 MipIndices )
00946 {
00947         KASSERT( m_CurrentMipLevel < m_nMipMesh );
00948 
00949         KSubTileDrawMipMesh*    pMipMesh = &m_pMipMesh[m_CurrentMipLevel];
00950 
00951         if( !pMipMesh->m_nIndex[MipIndices] )
00952                 return;
00953 
00954         KASSERT( pMipMesh->m_pIndex[MipIndices] );
00955         KASSERT( (m_nIndexListPos + pMipMesh->m_nIndex[MipIndices]) <= m_nIndexList );
00956 
00957         memcpy( &m_pIndexList[m_nIndexListPos], pMipMesh->m_pIndex[MipIndices], pMipMesh->m_nIndex[MipIndices] * sizeof( KINDEX ) );
00958         m_nIndexListPos += pMipMesh->m_nIndex[MipIndices];
00959 }
00960 
00961 //---------------------------------------------------------------------------------------------
00962 void KSubTileDraw::Draw()
00963 {
00964         KASSERT( m_CurrentMipLevel < m_nMipMesh );
00965 
00966         KSubTileDrawMipMesh*    pMipMesh = &m_pMipMesh[m_CurrentMipLevel];
00967         u32                                             nIndex = 0;
00968         s32                                             SubTileX = (s32)((GetpTileDraw()->GetPosX() + m_PosX) / TILE_SUBTILE_SIZE_X);
00969         s32                                             SubTileY = (s32)((GetpTileDraw()->GetPosY() + m_PosY) / TILE_SUBTILE_SIZE_Y);
00970         KSubTileDraw*                   pSubTile;
00971 
00972         // Flush le buffer d'index
00973         FlushIndexList();
00974 
00975         // Center
00976         AddIndexList( KSTMI_CENTER );
00977 
00978         // Up
00979         pSubTile = GetpTileDraw()->GetpLandscapeDraw()->GetpSubTileDraw( SubTileX, SubTileY + 1 );
00980         if( pSubTile && (pSubTile->GetCurrentMipLevel() > m_CurrentMipLevel ) )
00981                 AddIndexList( KSTMI_MIP_UP );
00982         else
00983                 AddIndexList( KSTMI_UP );
00984 
00985         // Down
00986         pSubTile = GetpTileDraw()->GetpLandscapeDraw()->GetpSubTileDraw( SubTileX, SubTileY - 1 );
00987         if( pSubTile && (pSubTile->GetCurrentMipLevel() > m_CurrentMipLevel ) )
00988                 AddIndexList( KSTMI_MIP_DOWN );
00989         else
00990                 AddIndexList( KSTMI_DOWN );
00991 
00992         // Left
00993         pSubTile = GetpTileDraw()->GetpLandscapeDraw()->GetpSubTileDraw( SubTileX - 1, SubTileY );
00994         if( pSubTile && (pSubTile->GetCurrentMipLevel() > m_CurrentMipLevel ) )
00995                 AddIndexList( KSTMI_MIP_LEFT );
00996         else
00997                 AddIndexList( KSTMI_LEFT );
00998 
00999         // Right
01000         pSubTile = GetpTileDraw()->GetpLandscapeDraw()->GetpSubTileDraw( SubTileX + 1, SubTileY );
01001         if( pSubTile && (pSubTile->GetCurrentMipLevel() > m_CurrentMipLevel ) )
01002                 AddIndexList( KSTMI_MIP_RIGHT );
01003         else
01004                 AddIndexList( KSTMI_RIGHT );
01005 
01006         if( !m_nIndexListPos )
01007                 return;
01008 
01009         KRenderFace             RenderFace;
01010 
01011         GetpTileDraw()->GetpRender()->SetShader( m_hShader );
01012         GetpTileDraw()->GetpRender()->SetTextureStageState( 0, KRTSS_ADDRESSU, KRTD_MIRROR );
01013         GetpTileDraw()->GetpRender()->SetTextureStageState( 0, KRTSS_ADDRESSV, KRTD_MIRROR );
01014         RenderFace.m_VertexType = KRVERTEX2;
01015         RenderFace.m_nVertex    = (u16)pMipMesh->m_nVertex;
01016         RenderFace.m_pVertex    = pMipMesh->m_pVertex;
01017         RenderFace.m_nIndices   = (u16)m_nIndexListPos;//pMipMesh->m_nIndex;
01018         RenderFace.m_pIndices   = m_pIndexList;//pMipMesh->m_pIndex;
01019 //      RenderFace.m_nIndices   = (u16)pMipMesh->m_nIndex[KSTMI_CENTER];
01020 //      RenderFace.m_pIndices   = pMipMesh->m_pIndex[KSTMI_CENTER];
01021         GetpTileDraw()->GetpRender()->DrawTriangles( RenderFace );
01022 
01023         // Affiche la bounding box
01024 //      GetpTileDraw()->GetpRender()->DrawBBox( m_pBBox );
01025 }
01026 
01027 //---------------------------------------------------------------------------------------------
01028 bool KSubTileDraw::GetRayIntersection( KVector& Orig, KVector& Dir, KVector* pPoint )
01029 {
01030         KVector                 p0, p1, p2;
01031         float                   t, u, v;
01032         KTILEHEIGHT             Height;
01033 
01034         s32                             SizeX = (s32)TILE_NCELLS_X / TILE_NSUBTILES_X;
01035         s32                             SizeY = (s32)TILE_NCELLS_Y / TILE_NSUBTILES_Y;
01036         s32                             CellPosX = (s32)(m_PosX + GetpTileDraw()->GetPosX()) / TILE_CELL_SIZE_X;
01037         s32                             CellPosY = (s32)(m_PosY + GetpTileDraw()->GetPosY()) / TILE_CELL_SIZE_Y;
01038 
01039         for( s32 cy = 0; cy < SizeY; cy ++ )
01040         {
01041                 for( s32 cx = 0; cx < SizeX; cx ++ )
01042                 {
01043                         // Triangle 1
01044                         p0.x    = (float)(CellPosX + cx) * TILE_CELL_SIZE_X;
01045                         p0.y    = (float)(CellPosY + cy) * TILE_CELL_SIZE_Y;
01046                         GetpTileDraw()->GetpLandscapeDraw()->GetCellHeight( CellPosX + cx, CellPosY + cy, &Height );
01047                         p0.z    = (float)Height;
01048 
01049                         p1.x    = (float)(CellPosX + cx) * TILE_CELL_SIZE_X;
01050                         p1.y    = (float)(CellPosY + cy + 1) * TILE_CELL_SIZE_Y;
01051                         GetpTileDraw()->GetpLandscapeDraw()->GetCellHeight( CellPosX + cx, CellPosY + cy + 1, &Height );
01052                         p1.z    = (float)Height;
01053 
01054                         p2.x    = (float)(CellPosX + cx + 1) * TILE_CELL_SIZE_X;
01055                         p2.y    = (float)(CellPosY + cy) * TILE_CELL_SIZE_Y;
01056                         GetpTileDraw()->GetpLandscapeDraw()->GetCellHeight( CellPosX + cx + 1, CellPosY + cy, &Height );
01057                         p2.z    = (float)Height;
01058 
01059                         if( IntersectTriangleCullNone( Orig, Dir, p0, p1, p2, &t, &u, &v ) )
01060                         {
01061                                 KVector Edge1 = p1 - p0;
01062                                 KVector Edge2 = p2 - p0;
01063                                 KVector Point = p0 + Edge1 * u + Edge2 * v;
01064 
01065                                 *pPoint = Point;
01066                                 //pPoint->x = (float)(CellPosX + cx) * TILE_CELL_SIZE_X;
01067                                 //pPoint->y = (float)(CellPosY + cy) * TILE_CELL_SIZE_Y;
01068                                 //pPoint->z = Point.z;//0.0f;
01069                                 return true;
01070                         }
01071 
01072                         // Triangle 2
01073                         p0.x    = (float)(CellPosX + cx + 1) * TILE_CELL_SIZE_X;
01074                         p0.y    = (float)(CellPosY + cy) * TILE_CELL_SIZE_Y;
01075                         GetpTileDraw()->GetpLandscapeDraw()->GetCellHeight( CellPosX + cx + 1, CellPosY + cy, &Height );
01076                         p0.z    = (float)Height;
01077 
01078                         p1.x    = (float)(CellPosX + cx) * TILE_CELL_SIZE_X;
01079                         p1.y    = (float)(CellPosY + cy + 1) * TILE_CELL_SIZE_Y;
01080                         GetpTileDraw()->GetpLandscapeDraw()->GetCellHeight( CellPosX + cx, CellPosY + cy + 1, &Height );
01081                         p1.z    = (float)Height;
01082 
01083                         p2.x    = (float)(CellPosX + cx + 1) * TILE_CELL_SIZE_X;
01084                         p2.y    = (float)(CellPosY + cy + 1) * TILE_CELL_SIZE_Y;
01085                         GetpTileDraw()->GetpLandscapeDraw()->GetCellHeight( CellPosX + cx + 1, CellPosY + cy + 1, &Height );
01086                         p2.z    = (float)Height;
01087 
01088                         if( IntersectTriangleCullNone( Orig, Dir, p0, p1, p2, &t, &u, &v ) )
01089                         {
01090                                 KVector Edge1 = p1 - p0;
01091                                 KVector Edge2 = p2 - p0;
01092                                 KVector Point = p0 + Edge1 * u + Edge2 * v;
01093 
01094                                 *pPoint = Point;
01095                                 //pPoint->x = (float)(CellPosX + cx) * TILE_CELL_SIZE_X;
01096                                 //pPoint->y = (float)(CellPosY + cy) * TILE_CELL_SIZE_Y;
01097                                 //pPoint->z = Point.z;//0.0f;
01098                                 return true;
01099                         }
01100                 }
01101         }
01102 
01103         return false;
01104 }

Generated on Sun Mar 25 20:02:12 2007 for Zythum Project by  doxygen 1.5.1-p1