魔兽3自适应地块贴图算法

 FW: http://www.cnitblog.com/sword/archive/2007/04/21/26000.aspx

整个贴图过程分为4个步骤:
1. 删除地块
2. 拼接地块
3. 排序地块层
4. 更新地块

有2种类型的地形纹理:
o_SimpleTexture.JPG
o_FullTexture.JPG
o_Base.JPG

根据上面这张排好索引的图片,加上效果图可以知道基本地块为:
1 | 2
8 | 16
然后是随机地块,数据如下:
s32 s_pBaseTexIndex_c[] = { 1, 2, 8, 16 };
s32 s_pRandTexIndex_c[] = { 0, 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 27, 28, 29, 30, 31 };

整个贴图算法都是基于上面这个基本索引而来.4个基本索引相加为27,是一个很特别的索引.

举2个例子:

1 |  2+1           1 | 3

8 | 16+8 =       8 | 24 =
o_Right.JPG

1     | 2                 1 | 2

8+1 | 16+2 =       9 | 18 =
o_Down.JPG
一个格子最多可以贴4个地块,也就是4层地块,下面是基本数据定义.

// 地形顶点数据
struct TeVertex
{
         f32            fHeight;          ///< 地形高度值
         Vector3f v3Normal; ///< 地形顶点法向量
};

// 地形地块纹理数据
struct TeTile
{
         s8 Block[TE_TILE_COUNT]; ///< 纹理中的一块
         u8 Texture[TE_TILE_COUNT]; ///< 纹理ID,255代表空
};

首先初始化一个32*32的地形数据:

m_pVertex = new TeVertex[32*32];
m_pTile = new TeTile[32*32];

for( i = 0; i < 32*32; ++i )
{
       nBlock = s_pRandTexIndex_c[rand() % 18];

       m_pVertex[i].fHeight = 0.0f;

       m_pTile[i].Block[0] = nBlock;
       m_pTile[i].Texture[0] = 0;

       m_pTile[i].Block[1] = 0;
       m_pTile[i].Texture[1] = 255;

       m_pTile[i].Block[2] = 0;
       m_pTile[i].Texture[2] = 255;

       m_pTile[i].Block[3] = 0;
       m_pTile[i].Texture[3] = 255;
}

在拼接之前首先是找出4个要拼接的格子,如图:
o_FindTile.JPG
1. 删除地块
         1-1: 如果当前地块第0层的纹理索引不为0并且Block索引是随机地块的话,格子的数据需要调整, 算法为用27减去除第0层外所有有效层的Block索引,最后的结果赋予第0层的Block.
   
         1-2: 循环直到找出如果4个格子的某一层的Texture索引都相同,并找出所在的层,然后在做以下判断:
              1-2-1: 如果这4个格子的这4层的Block索引都是随机地块索引,并且Texture索引比要贴的Texture索引大的话,则这4个格子的相应Block索引都要变为27减去基本索引. 然后回到2-1.
        
              1-2-2: 1-2-1不成立的话,判断4个格子的Block是否可删除,条件是用当前地块的当前层的Block索引减去基本地块,如果是随机地块索引(除开0和27)则不合法,其余结果是合法的.
        
              1-2-3: 将4个格子的对应层的Block索引都减去一个值.如果是Block索引是随机地块索引,则用27减去基本地块索引.否则用自身的Block索引减去基本索引值,如果减出来的结果是0的话, 则设置这个格子的这一层的Texture索引为255

2. 拼接地块
         首先是找出要拼接纹理对应的层次,这中间涉及到调节层次数据,看下面的代码.接下来就是修改Block索引,主要的操作就是加上基本索引.在这中间涉及到的判断相当的多,还是看代码直接:),值得注意的是当设置的地块Block索引为27的时候需要特殊处理.

3. 排序地块层
         这一步最简单,一共才4层,最简单的冒泡排序就行了:)

4. 更新地块
         把一个地块中所有的地块索引相加,索引为随机地块的不参与,如果最后的结果为27那么需要对这个地块的数据做调整.如果这个格子的Texture索引不是0的话,把这个格子的第0层的Block索引设置为随机地块索引.如果是0的话,则第0层的Texture索引变为第1层的Texture索引,并且把第2层的数据复制到第1层,把第3层的数据复制到第2层,第3层的数据设置为空.
   
         由于网上查不到相关的资料,上面这些都是我通过观察war3的编辑器总结出来的,希望可以给在做类似war3这种地形贴图的朋友一些帮助:),有不明白的地方可以在QQ(76537477)上联系我.

最后贴上我的效果图和核心代码:
o_Terrain.JPG

算法的基本代码(为了简单明了,下面的代码是简化了的, 这里实在是不知道怎么排版啊)

 

#define  TE_TILE_COUNT     4
#define  TE_INVALID_TILE   255
#define  TE_TILE_LEN       2.0f
#define  TE_TEX_BASE       4  //  地形纹理基本变换数
#define  TE_MAX_TEX        8  //  地形最多支持8种不同的纹理
#define  TE_TEX_RAND_S     2  //  256的地形纹理最大变换数
#define  TE_TEX_RAND_C     18  //  512的地形纹理最大变换数
#define  TE_TEX_COUNT_S    16  //  Simple
#define  TE_TEX_COUNT_C    32  //  Complex//-------------&-------------
// ---------------------------&-------------------------
void  SetTile(  const  Vector3f  & v3Pos )
{
if ( m_nSelectTexture  <   0   ||  m_nSelectTexture  >=  m_vecTexture.Size() )
     
return ;
f32 fDis 
=  TE_TILE_LEN  /   2.0f ;
s32 nLDTile 
=  (s32)((v3Pos.y  -  fDis)  /  TE_TILE_LEN)  *  m_nTileWid  +  (s32)((v3Pos.x  -  fDis)  /  TE_TILE_LEN);
s32 nRDTile 
=  (s32)((v3Pos.y  -  fDis)  /  TE_TILE_LEN)  *  m_nTileWid  +  (s32)((v3Pos.x  +  fDis)  /  TE_TILE_LEN);
s32 nRUTile 
=  (s32)((v3Pos.y  +  fDis)  /  TE_TILE_LEN)  *  m_nTileWid  +  (s32)((v3Pos.x  +  fDis)  /  TE_TILE_LEN);
s32 nLUTile 
=  (s32)((v3Pos.y  +  fDis)  /  TE_TILE_LEN)  *  m_nTileWid  +  (s32)((v3Pos.x  -  fDis)  /  TE_TILE_LEN);

s32 i 
=   0 , nLDLayer  =   0 , nRDLayer  =   0 , nRULayer  =   0 , nLULayer  =   0 ;
s32 nLDBlock, nRDBlock, nRUBlock, nLUBlock;
BOOL bLDCheck 
=  FALSE, bRDCheck  =  FALSE, bRUCheck  =  FALSE, bLUCheck  =  FALSE; //  更新当前周围的地块属性

UpdateTileAttribute( nLDTile, nRDTile, nRUTile, nLUTile ); 
//  找出对应的层
for ( i  =   0 ; i  <  TE_LAYERS;  ++ i )
{
     
if ( m_pTile[nLDTile].Texture[i]  ==  m_nSelectTexture )
     
{
      nLDLayer 
=  i;
      bLDCheck 
=  TRUE;
     }

     
else   if ! bLDCheck  &&  m_pTile[nLDTile].Texture[i]  !=  TE_INVALID_TILE )
     
{
      
++ nLDLayer;
     }
     
     
if ( m_pTile[nRDTile].Texture[i]  ==  m_nSelectTexture )
     
{
      nRDLayer 
=  i;
      bRDCheck 
=  TRUE;
     }

     
else   if ! bRDCheck  &&  m_pTile[nRDTile].Texture[i]  !=  TE_INVALID_TILE )
     
{
      
++ nRDLayer;
     }
     
     
if ( m_pTile[nRUTile].Texture[i]  ==  m_nSelectTexture )
     
{
      nRULayer 
=  i;
      bRUCheck 
=  TRUE;
     }

     
else   if ! bRUCheck  &&  m_pTile[nRUTile].Texture[i]  !=  TE_INVALID_TILE )
     
{
      
++ nRULayer;
     }
     
     
if ( m_pTile[nLUTile].Texture[i]  ==  m_nSelectTexture )
     
{
      nLULayer 
=  i;
      bLUCheck 
=  TRUE;
     }

     
else   if ! bLUCheck  &&  m_pTile[nLUTile].Texture[i]  !=  TE_INVALID_TILE )
     
{
      
++ nLULayer;
     }

}

     
if ! bLDCheck )
     nLDLayer 
=  AdjustTileLayer( nLDTile,  2  );
     
if ! bRDCheck )
     nRDLayer 
=  AdjustTileLayer( nRDTile,  3  );
     
if ! bRUCheck )
     nRULayer 
=  AdjustTileLayer( nRUTile,  1  );
     
if ! bLUCheck )
     nLULayer 
=  AdjustTileLayer( nLUTile,  0  );
s32 nLDTexture 
=  m_pTile[nLDTile].Texture[nLDLayer];
if ( nLDTexture  !=  TE_INVALID_TILE )
{
     s32 nRDTexture 
=  m_pTile[nRDTile].Texture[nRDLayer];
     s32 nRUTexture 
=  m_pTile[nRUTile].Texture[nRULayer];
     s32 nLUTexture 
=  m_pTile[nLUTile].Texture[nLULayer]; 
    
if ( nLDTexture  ==  nRDTexture  &&  nLDTexture  ==  nRUTexture  &&  nLDTexture  ==  nLUTexture )
     
{
      
if ( (m_pTile[nLDTile].Texture[TE_LAYERS - 1 !=  TE_INVALID_TILE  ||  
          m_pTile[nRDTile].Texture[TE_LAYERS
- 1 !=  TE_INVALID_TILE  ||
          m_pTile[nRUTile].Texture[TE_LAYERS
- 1 !=  TE_INVALID_TILE  ||
          m_pTile[nLUTile].Texture[TE_LAYERS
- 1 !=  TE_INVALID_TILE) )
      
{
       
if ( (nLDTexture  ==  m_nSelectTexture)  &&  
           (m_pTile[nLDTile].Block[nLDLayer] 
==  s_pBaseTexIndex_c[ 2 ||
            m_pTile[nRDTile].Block[nRDLayer] 
==  s_pBaseTexIndex_c[ 3 ||  
            m_pTile[nRUTile].Block[nRULayer] 
==  s_pBaseTexIndex_c[ 1 ||  
            m_pTile[nLUTile].Block[nLULayer] 
==  s_pBaseTexIndex_c[ 0 ] ) )
       
{
        
goto  _SORT_LAYER;
       }
       nLDBlock  =  m_pTile[nLDTile].Block[nLDLayer];
       
if ( m_pTile[nLDTile].Texture[nLDLayer]  !=   0   &&  (nLDBlock  ==   0   ||   ! IsValidRandBlock(nLDBlock)) )
        nLDBlock 
=  m_pTile[nLDTile].Block[nLDLayer]  +  s_pBaseTexIndex_c[ 2 ];       nRDBlock  =  m_pTile[nRDTile].Block[nRDLayer];
       
if ( m_pTile[nRDTile].Texture[nRDLayer]  !=   0   &&  (nRDBlock  ==   0   ||   ! IsValidRandBlock(nRDBlock)) )
        nRDBlock 
=  m_pTile[nRDTile].Block[nRDLayer]  +  s_pBaseTexIndex_c[ 3 ];       nRUBlock  =  m_pTile[nRUTile].Block[nRULayer];
       
if ( m_pTile[nRUTile].Texture[nRULayer]  !=   0   &&  (nRUBlock  ==   0   ||   ! IsValidRandBlock(nRUBlock)) )
        nRUBlock 
=  m_pTile[nRUTile].Block[nRULayer]  +  s_pBaseTexIndex_c[ 1 ];       nLUBlock  =  m_pTile[nLUTile].Block[nLULayer];
       
if ( m_pTile[nLUTile].Texture[nLULayer]  !=   0   &&  (nLUBlock  ==   0   ||   ! IsValidRandBlock(nLUBlock)) )
        nLUBlock 
=  m_pTile[nLUTile].Block[nLULayer]  +  s_pBaseTexIndex_c[ 0 ];        if ( IsValidBlock(nLDBlock)  &&  IsValidTileBlock( nLDBlock ) )
        SetTileAttribute( nLDTile, nLDLayer, nLDBlock );
    
       
if ( IsValidBlock(nRDBlock)  &&  IsValidTileBlock( nRDBlock ) )
        SetTileAttribute( nRDTile, nRDLayer, nRDBlock );
    
       
if ( IsValidBlock(nRUBlock)  &&  IsValidTileBlock( nRUBlock ) )
        SetTileAttribute( nRUTile, nRULayer, nRUBlock );
    
       
if ( IsValidBlock(nLUBlock)  &&  IsValidTileBlock( nLUBlock ) )
        SetTileAttribute( nLUTile, nLULayer, nLUBlock );       
goto  _SORT_LAYER;
      }

      
else   if ( m_pTile[nLDTile].Block[nLDLayer]  +  s_pBaseTexIndex_c[ 2 >=  TE_TEX_COUNT_C  ||
        m_pTile[nRDTile].Block[nRDLayer] 
+  s_pBaseTexIndex_c[ 3 >=  TE_TEX_COUNT_C  ||
        m_pTile[nRUTile].Block[nRULayer] 
+  s_pBaseTexIndex_c[ 1 >=  TE_TEX_COUNT_C  ||
        m_pTile[nLUTile].Block[nLULayer] 
+  s_pBaseTexIndex_c[ 0 >=  TE_TEX_COUNT_C )
      
{
       
goto  _SORT_LAYER;
      }

     }

}
    nLDBlock  =  m_pTile[nLDTile].Block[nLDLayer]  +  s_pBaseTexIndex_c[ 2 ];
nRDBlock 
=  m_pTile[nRDTile].Block[nRDLayer]  +  s_pBaseTexIndex_c[ 3 ];
nRUBlock 
=  m_pTile[nRUTile].Block[nRULayer]  +  s_pBaseTexIndex_c[ 1 ];
nLUBlock 
=  m_pTile[nLUTile].Block[nLULayer]  +  s_pBaseTexIndex_c[ 0 ]; if ! IsValidTileBlock( nLDBlock ) )
     
goto  _SORT_LAYER; if ! IsValidTileBlock( nRDBlock ) )
     
goto  _SORT_LAYER; if ! IsValidTileBlock( nRUBlock ) )
     
goto  _SORT_LAYER; if ! IsValidTileBlock( nLUBlock ) )
     
goto  _SORT_LAYER;SetTileAttribute( nLDTile, nLDLayer, nLDBlock );
SetTileAttribute( nRDTile, nRDLayer, nRDBlock );
SetTileAttribute( nRUTile, nRULayer, nRUBlock );
SetTileAttribute( nLUTile, nLULayer, nLUBlock );_SORT_LAYER:
SortLayerTile( nLDTile );
SortLayerTile( nRDTile );
SortLayerTile( nRUTile );
SortLayerTile( nLUTile );
}
// -------------&-------------
// ---------------------------&-------------------------
s32 AdjustTileLayer( s32 nTile, s32 nIndex )
{
BOOL bCheck 
=  FALSE, bFindLayer  =  FALSE;
s32 i, nMinLayer, nRetLayer 
=   0 ;
for ( i  =   0 ; i  <  TE_LAYERS;  ++ i )
{
     
if ( m_pTile[nTile].Texture[i]  ==  TE_INVALID_TILE )
     
{
      bCheck 
=  TRUE;
      m_pTile[nTile].Texture[i] 
=  m_nSelectTexture;
      
if ( m_nSelectTexture  ==   0  )
       m_pTile[nTile].Block[i] 
=   27 ;
      
break ;
     }

}

if ! bCheck )
{
     nMinLayer 
=   0 ;      for ( i  =   0 ; i  <  TE_LAYERS;  ++ i )
     
{
      
if ( m_pTile[nTile].Texture[i]  ==  m_nSelectTexture )
      
{
       bFindLayer 
=  TRUE;
       m_pTile[nTile].Texture[i] 
=  m_nSelectTexture;
       
break ;
      }

     }

     
if ! bFindLayer )
     
{
      
for ( i  =   0 ; i  <  TE_LAYERS  -   1 ++ i )
      
{
       m_pTile[nTile].Texture[i] 
=  m_pTile[nTile].Texture[i + 1 ];
       m_pTile[nTile].Block[i] 
=  m_pTile[nTile].Block[i + 1 ];
      }
     
           
for ( i  =   0 ; i  <  TE_LAYERS  -   1 ++ i )
      
{
       
if ( m_pTile[nTile].Texture[i]  ==  m_nSelectTexture )
       
{
        m_pTile[nTile].Texture[TE_LAYERS
- 1 =   0 ;
        m_pTile[nTile].Block[TE_LAYERS
- 1 =  s_pRandTexIndex_c[rand() % TE_TEX_RAND_C];         goto  _SPECIAL_LAYER;
       }

      }
      m_pTile[nTile].Texture[TE_LAYERS - 1 =  m_nSelectTexture;
      m_pTile[nTile].Block[TE_LAYERS
- 1 =   0 ;
     }

}
_SPECIAL_LAYER:
//  for( i = 0; i < TE_LAYERS; ++i )
//  {
//      if( m_pTile[nTile].Texture[i] < m_pTile[nTile].Texture[nMinLayer] )
//      {
//       nMinLayer = i;
//      }
//  }for( i = 0; i < TE_LAYERS; ++i )
{
     
if ( m_pTile[nTile].Texture[i]  ==  m_nSelectTexture )
     
{
      nRetLayer 
=  i;
      
goto  _LAYER_RETURN;
     }

}

for ( i  =   0 ; i  <  TE_LAYERS;  ++ i )
{
     
if ( m_pTile[nTile].Texture[i]  ==  TE_INVALID_TILE )
     
{
      nRetLayer 
=  i;
      
goto  _LAYER_RETURN;
     }

}
nRetLayer  =  TE_LAYERS  -   1 ;_LAYER_RETURN: return  nRetLayer;
}
// +-------------&-------------
// +---------------------------&-------------------------
void  SortLayerTile( s32 nTile )
{
BOOL bBaseLayer 
=  FALSE;
s32 nBaseLayer 
=   - 1 ;
s32 i, j, nTex, nBlock;
for ( i  =   0 ; i  <  TE_LAYERS;  ++ i )
{
     
for ( j  =  i  +   1 ; j  <  TE_LAYERS;  ++ j )
     
{
      
if ( m_pTile[nTile].Texture[i]  >  m_pTile[nTile].Texture[j] )
      
{
       nTex 
=  m_pTile[nTile].Texture[i];
       nBlock 
=  m_pTile[nTile].Block[i];       m_pTile[nTile].Texture[i]  =  m_pTile[nTile].Texture[j];
       m_pTile[nTile].Block[i] 
=  m_pTile[nTile].Block[j];       m_pTile[nTile].Texture[j]  =  nTex;
       m_pTile[nTile].Block[j] 
=  nBlock;
      }
     }

}
nBlock  =   0 ;
for ( i  =   0 ; i  <  TE_LAYERS;  ++ i )
{
     
if ! IsValidRandBlock( m_pTile[nTile].Block[i] ) )
     
{
      nBlock 
+=  m_pTile[nTile].Block[i];
     }

}
if ( nBlock  ==   27  )
{
     
if ( m_pTile[nTile].Texture[ 0 ==   0  )
     
{
      m_pTile[nTile].Texture[
0 =  m_pTile[nTile].Texture[ 1 ];
      m_pTile[nTile].Block[
0 =   27 ;       for ( i  =   1 ; i  <  TE_LAYERS  -   1 ++ i )
      
{
       m_pTile[nTile].Texture[i] 
=  m_pTile[nTile].Texture[i + 1 ];
       m_pTile[nTile].Block[i] 
=  m_pTile[nTile].Block[i + 1 ];
      }
      m_pTile[nTile].Texture[TE_LAYERS - 1 =  TE_INVALID_TILE;
      m_pTile[nTile].Block[TE_LAYERS
- 1 =   0 ;
     }

     
else
     
{
      m_pTile[nTile].Block[
0 =   27 ;
     }

}

}
// -------------&-------------
// ---------------------------&-------------------------
BOOL IsValidTileBlock( s32 nBlock )  const
{
s32 i 
=   0 ; if ( nBlock  ==   0   ||  nBlock  ==   27  )
     
return  TRUE; for ( ; i  <  TE_TEX_RAND_C;  ++ i )
{
     
if ( nBlock  ==  s_pRandTexIndex_c[i] )
      
return  FALSE;
}
return  TRUE;
}
// -------------&-------------
// ---------------------------&-------------------------
BOOL IsValidRandBlock( s32 nBlock )  const
{
s32 i 
=   0 ;
for ( ; i  <  TE_TEX_RAND_C;  ++ i )
{
     
if ( nBlock  ==  s_pRandTexIndex_c[i] )
      
return  TRUE;
}
return  FALSE;
}
// +-------------&-------------
// +---------------------------&-------------------------
s32 CheckLayerTile( s32 nTile, s32 nTexture )
{
s32 i;
for ( i  =   0 ; i  <  TE_TILE_COUNT;  ++ i )
{
     
if ( m_pTile[nTile].Texture[i]  !=  TE_INVALID_TILE  &&  m_pTile[nTile].Texture[i]  ==  nTexture )
      
return  i;
}
return   - 1 ;
}
// +-------------&-------------
// +---------------------------&-------------------------
void  UpdateTileAttribute( s32 nLDTile, s32 nRDTile, s32 nRUTile, s32 nLUTile )
{
s32 i, nBlock, nLDTexture;
s32 nLDLayer, nRDLayer, nRULayer, nLULayer;
if ( IsValidRandBlock(m_pTile[nLDTile].Block[ 0 ])  &&  m_pTile[nLDTile].Texture[ 0 !=   0  )
{
     nBlock 
=   27 ;
     
for ( i  =   1 ; i  <  TE_LAYERS;  ++ i )
     
{
      
if ( m_pTile[nLDTile].Texture[i]  !=  TE_INVALID_TILE )
      
{
       nBlock 
-=  m_pTile[nLDTile].Block[i];
      }

     }
     m_pTile[nLDTile].Block[ 0 =  nBlock;
}
if ( IsValidRandBlock(m_pTile[nRDTile].Block[ 0 ])  &&  m_pTile[nRDTile].Texture[ 0 !=   0  )
{
     nBlock 
=   27 ;
     
for ( i  =   1 ; i  <  TE_LAYERS;  ++ i )
     
{
      
if ( m_pTile[nRDTile].Texture[i]  !=  TE_INVALID_TILE )
      
{
       nBlock 
-=  m_pTile[nRDTile].Block[i];
      }

     }
     m_pTile[nRDTile].Block[ 0 =  nBlock;
}
if ( IsValidRandBlock(m_pTile[nRUTile].Block[ 0 ])  &&  m_pTile[nRUTile].Texture[ 0 !=   0  )
{
     nBlock 
=   27 ;
     
for ( i  =   1 ; i  <  TE_LAYERS;  ++ i )
     
{
      
if ( m_pTile[nRUTile].Texture[i]  !=  TE_INVALID_TILE )
      
{
       nBlock 
-=  m_pTile[nRUTile].Block[i];
      }

     }
     m_pTile[nRUTile].Block[ 0 =  nBlock;
}
if ( IsValidRandBlock(m_pTile[nLUTile].Block[ 0 ])  &&  m_pTile[nLUTile].Texture[ 0 !=   0  )
{
     nBlock 
=   27 ;
     
for ( i  =   1 ; i  <  TE_LAYERS;  ++ i )
     
{
      
if ( m_pTile[nLUTile].Texture[i]  !=  TE_INVALID_TILE )
      
{
       nBlock 
-=  m_pTile[nLUTile].Block[i];
      }

     }
     m_pTile[nLUTile].Block[ 0 =  nBlock;
}
//  找出对应的层
for ( i  =   0 ; i  <  TE_TILE_COUNT;  ++ i )
{
     nLDLayer 
=  i;
     nLDTexture 
=  m_pTile[nLDTile].Texture[i];      if ( nLDTexture  ==  m_nSelectTexture )
      
continue ;     nRDLayer  =  CheckLayerTile( nRDTile, nLDTexture );
     
if ( nRDLayer  ==   - 1  )
      
continue ;     nRULayer  =  CheckLayerTile( nRUTile, nLDTexture );
     
if ( nRULayer  ==   - 1  )
      
continue ;     nLULayer  =  CheckLayerTile( nLUTile, nLDTexture );
     
if ( nLULayer  ==   - 1  )
      
continue ;      if ( IsValidRandBlock( m_pTile[nLDTile].Block[nLDLayer] )  &&
         IsValidRandBlock( m_pTile[nRDTile].Block[nRDLayer] ) 
&&  
         IsValidRandBlock( m_pTile[nRUTile].Block[nRULayer] ) 
&&  
         IsValidRandBlock( m_pTile[nLUTile].Block[nLULayer] ) )
     
{
      
if ( m_nSelectTexture  <  nLDTexture )
      
{
       m_pTile[nLDTile].Block[nLDLayer] 
=   27   -  s_pBaseTexIndex_c[ 2 ];
       m_pTile[nRDTile].Block[nRDLayer] 
=   27   -  s_pBaseTexIndex_c[ 3 ];
       m_pTile[nRUTile].Block[nRULayer] 
=   27   -  s_pBaseTexIndex_c[ 1 ];
       m_pTile[nLUTile].Block[nLULayer] 
=   27   -  s_pBaseTexIndex_c[ 0 ];
      }

      
continue ;
     }
      if ! IsValidSubBlock( nLDTile, nLDLayer,  2  )  ||  
         
! IsValidSubBlock( nRDTile, nRDLayer,  3  )  ||  
         
! IsValidSubBlock( nRUTile, nRULayer,  1  )  ||  
         
! IsValidSubBlock( nLUTile, nLULayer,  0  ) )
     
{
      
continue ;
     }
     ChangeBlock( nLDTile, nLDLayer,  2  );
     ChangeBlock( nRDTile, nRDLayer, 
3  );
     ChangeBlock( nRUTile, nRULayer, 
1  );
     ChangeBlock( nLUTile, nLULayer, 
0  );
}

}
// +-------------&-------------
// +---------------------------&-------------------------
BOOL IsValidSubBlock( s32 nTile, s32 nLayer, s32 nIndex )
{
s32 nBlock 
=  m_pTile[nTile].Block[nLayer]  -  s_pBaseTexIndex_c[nIndex]; if ! IsValidBlock( nBlock ) )
     
return  FALSE; if ( nBlock  ==   0   ||   ! IsValidRandBlock( nBlock ) )
     
return  TRUE; return  TRUE;
}
// +-------------&-------------
// +---------------------------&-------------------------
void  ChangeBlock( s32 nTile, s32 nLayer, s32 nIndex )
{
s32 nBlock 
=  m_pTile[nTile].Block[nLayer]; if ! IsValidRandBlock( nBlock ) )
{
     nBlock 
=  nBlock  -  s_pBaseTexIndex_c[nIndex];
     m_pTile[nTile].Block[nLayer] 
=  nBlock;      if ( nBlock  ==   0  )
     
{
      m_pTile[nTile].Block[nLayer] 
=   0 ;
      m_pTile[nTile].Texture[nLayer] 
=  TE_INVALID_TILE;
     }

}

else
{
     m_pTile[nTile].Block[nLayer] 
=   27   -  s_pBaseTexIndex_c[nIndex];
}

}
// -------------&-------------
// ---------------------------&-------------------------
void  SetTileAttribute( s32 nTile, s32 nLayer, s32 nBlock )
{
if ( nBlock  ==   27  )
{
     
//  nBlock = s_pRandTexIndex_c[rand() % TE_TEX_RAND_C];     s32 i = 0;
      for ( ; i  <  TE_TILE_COUNT;  ++ i )
     
{
      
if ( m_pTile[nTile].Texture[i]  <  m_nSelectTexture )
      
{
       m_pTile[nTile].Block[i] 
=   0 ;
       m_pTile[nTile].Texture[i] 
=  TE_INVALID_TILE;
      }

     }
     m_pTile[nTile].Texture[nLayer]  =  m_nSelectTexture;
}
if ! IsValidBlock( nBlock ) )
{
     nBlock 
=   0 ;
}
if ( nBlock  >=   32  )
{
     nBlock 
=   27 ;
}
m_pTile[nTile].Block[nLayer]  =  nBlock;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值