void MapEditor::Filter(int nFilteTimes, float filterPar) { ATLASSERT(nFilteTimes > 0); for(int i = 0; i < nFilteTimes; ++i) { FilterHeightField(m_pMapData, m_height, filterPar); } m_isModified = true; m_isDrawed = false; }
void MakeTerrainFault(float* field,int size,int iterations,int maxDelta,int minDelta,int iterationsPerFilter,float filter) { int x1,y1,x2,y2,dx1,dy1,dx2,dy2,i,dHeight; /* Clear the height field */ for (i=0;i<size*size;i++) { field[i] = 0.0f; } for (i=0;i<iterations;i++) { /* Calculate the dHeight for this iteration (linear interpolation from maxDelta to minDelta */ dHeight = maxDelta - ((maxDelta-minDelta)*i)/iterations; /* Pick two random points on the field for the line (make sure they're not identical) */ x1 = rand()%size; y1 = rand()%size; do { x2 = rand()%size; y2 = rand()%size; }while (x2==x1 && y2==y1); /* dx1,dy1 is a vector in the direction of the line */ dx1 = x2 - x1; dy1 = y2 - y1; for (x2 = 0;x2<size;x2++) for (y2 = 0;y2<size;y2++) { /* dx2,dy2 is a vector from x1,y1 to the candidate point */ dx2 = x2-x1; dy2 = y2-y1; /* if z component of the cross product is 'up', then elevate this point */ if (dx2*dy1 - dx1*dy2 > 0) { field[x2+size*y2] += (float)(dHeight); } } /* Erode terrain */ if (iterationsPerFilter!=0 && (i%iterationsPerFilter)==0) FilterHeightField(field,size,filter); } /* Normalize terrain (height field values in the range 0-1) */ NormalizeTerrain(field,size); }
//-------------------------------------------------------------- // Name: CTERRAIN::MakeTerrainFault - public // Description: Create a height data set using the "Fault Formation" // algorithm. Thanks a lot to Jason Shankel for this code! // Arguments: -iSize: Desired size of the height map // -iIterations: Number of detail passes to make // -iMinDelta, iMaxDelta: the desired min/max heights // -iIterationsPerFilter: Number of passes per filter // -fFilter: Strength of the filter // Return Value: A boolean value: -true: successful creation // -false: unsuccessful creation //-------------------------------------------------------------- bool CTERRAIN::MakeTerrainFault( int iSize, int iIterations, int iMinDelta, int iMaxDelta, float fFilter ) { float* fTempBuffer; int iCurrentIteration; int iHeight; int iRandX1, iRandZ1; int iRandX2, iRandZ2; int iDirX1, iDirZ1; int iDirX2, iDirZ2; int x, z; int i; if( m_heightData.m_ucpData ) UnloadHeightMap( ); m_iSize= iSize; //allocate the memory for our height data m_heightData.m_ucpData= new unsigned char [m_iSize*m_iSize]; fTempBuffer= new float [m_iSize*m_iSize]; //check to see if memory was successfully allocated if( m_heightData.m_ucpData==NULL ) { //something is seriously wrong here g_log.Write( LOG_FAILURE, "Could not allocate memory for height map" ); return false; } //check to see if memory was successfully allocated if( fTempBuffer==NULL ) { //something is seriously wrong here g_log.Write( LOG_FAILURE, "Could not allocate memory for height map" ); return false; } //clear the height fTempBuffer for( i=0; i<m_iSize*m_iSize; i++ ) fTempBuffer[i]= 0; for( iCurrentIteration=0; iCurrentIteration<iIterations; iCurrentIteration++ ) { //calculate the height range (linear interpolation from iMaxDelta to //iMinDelta) for this fault-pass iHeight= iMaxDelta - ( ( iMaxDelta-iMinDelta )*iCurrentIteration )/iIterations; //pick two points at random from the entire height map iRandX1= rand( )%m_iSize; iRandZ1= rand( )%m_iSize; //check to make sure that the points are not the same do { iRandX2= rand( )%m_iSize; iRandZ2= rand( )%m_iSize; } while ( iRandX2==iRandX1 && iRandZ2==iRandZ1 ); //iDirX1, iDirZ1 is a vector going the same direction as the line iDirX1= iRandX2-iRandX1; iDirZ1= iRandZ2-iRandZ1; for( z=0; z<m_iSize; z++ ) { for( x=0; x<m_iSize; x++ ) { //iDirX2, iDirZ2 is a vector from iRandX1, iRandZ1 to the current point (in the loop) iDirX2= x-iRandX1; iDirZ2= z-iRandZ1; //if the result of ( iDirX2*iDirZ1 - iDirX1*iDirZ2 ) is "up" (above 0), //then raise this point by iHeight if( ( iDirX2*iDirZ1 - iDirX1*iDirZ2 )>0 ) fTempBuffer[( z*m_iSize )+x]+= ( float )iHeight; } } //erode terrain FilterHeightField( fTempBuffer, fFilter ); } //normalize the terrain for our purposes NormalizeTerrain( fTempBuffer ); //transfer the terrain into our class's unsigned char height buffer for( z=0; z<m_iSize; z++ ) { for( x=0; x<m_iSize; x++ ) SetHeightAtPoint( ( unsigned char )fTempBuffer[( z*m_iSize )+x], x, z ); } //delete temporary buffer if( fTempBuffer ) { //delete the data delete[] fTempBuffer; } return true; }