void TerrainLattice::Paint(ParaEngine::TextureEntity* detailTexture, float brushRadius, float brushIntensity, float maxIntensity, bool erase, float x, float y) { Terrain * AffectedTerrainTiles[4]; Terrain * pCenterTerrain = GetTerrainAtPoint(x, y); if(pCenterTerrain==NULL || pCenterTerrain->IsEmpty()) return; float fLogicalBrushRadius = brushRadius; AffectedTerrainTiles[0] = GetTerrainAtPoint(x+fLogicalBrushRadius, y+fLogicalBrushRadius); AffectedTerrainTiles[1] = GetTerrainAtPoint(x+fLogicalBrushRadius, y-fLogicalBrushRadius); AffectedTerrainTiles[2] = GetTerrainAtPoint(x-fLogicalBrushRadius, y+fLogicalBrushRadius); AffectedTerrainTiles[3] = GetTerrainAtPoint(x-fLogicalBrushRadius, y-fLogicalBrushRadius); for(int i=0;i<4; i++) { Terrain * pTerrain = AffectedTerrainTiles[i]; bool bDraw = true; for(int k=i-1;k>=0; --k) { if(AffectedTerrainTiles[k] == pTerrain) { bDraw = false; break; } } if(bDraw && pTerrain != NULL && (! pTerrain->IsEmpty())) { pTerrain->SetModified(true, MODIFIED_TEXTURE); pTerrain->Paint(detailTexture, brushRadius, brushIntensity, maxIntensity, erase, x,y); } } }
void TerrainLattice::SetTerrainInfo(float x,float y,float radius,uint32 data,uint32 bitMask,uint32 bitOffset) { if(SnapPointToVertexGrid(x,y) == false) return; Terrain* pTerrain = GetTerrainAtPoint(x,y); if(pTerrain == NULL || pTerrain->IsEmpty()) return; float vertexSpacing = pTerrain->GetVertexSpacing(); float minX = x - radius; float minY = y - radius; int count = (int)(radius * 2.f / vertexSpacing); if(count < 1) count = 1; for(int i=0;i<count;i++) { for(int j=0;j<count;j++) { float curX = minX + i * vertexSpacing; float curY = minY + j* vertexSpacing; SetVertexInfo(curX,curY,data,bitMask,bitOffset); } } Terrain* affectedTerrainTiles[4]; affectedTerrainTiles[0] = GetTerrainAtPoint(x+radius, y+radius); affectedTerrainTiles[1] = GetTerrainAtPoint(x+radius, y-radius); affectedTerrainTiles[2] = GetTerrainAtPoint(x-radius, y+radius); affectedTerrainTiles[3] = GetTerrainAtPoint(x-radius, y-radius); for(int i=0;i<4; i++) { Terrain * pTerrain = affectedTerrainTiles[i]; bool bDraw = true; for(int k=i-1;k>=0; --k) { if(affectedTerrainTiles[k] == pTerrain) { bDraw = false; break; } } if(bDraw && pTerrain != NULL && (!pTerrain->IsEmpty())) { pTerrain->RefreshTerrainInfo(); } } }
void TerrainLattice::RecalculateTerrainGeometry(float x, float y, float fAffectedRadius) { Terrain * AffectedTerrainTiles[4]; AffectedTerrainTiles[0] = GetTerrainAtPoint(x+fAffectedRadius, y+fAffectedRadius); AffectedTerrainTiles[1] = GetTerrainAtPoint(x+fAffectedRadius, y-fAffectedRadius); AffectedTerrainTiles[2] = GetTerrainAtPoint(x-fAffectedRadius, y+fAffectedRadius); AffectedTerrainTiles[3] = GetTerrainAtPoint(x-fAffectedRadius, y-fAffectedRadius); for(int i=0;i<4; i++) { Terrain * pTerrain = AffectedTerrainTiles[i]; bool bDraw = true; for(int k=i-1;k>=0; --k) { if(AffectedTerrainTiles[k] == pTerrain) { bDraw = false; break; } } if(bDraw && pTerrain != NULL && (!pTerrain->IsEmpty())) { pTerrain->RecalcGeometry(); if(m_useGeoMipmap) pTerrain->BuildGeoMipmapBuffer(); } } CGlobals::GetOceanManager()->CleanupTerrainCache(); }
bool TerrainLattice::Apply_HeightField_to_Rect( TTerrain* pHeightField, float x, float y, bool bRecalculateGeometry, bool bRecoverHeightData) { Terrain *pTerrain = GetTerrainAtPoint(x, y); if(pTerrain==NULL || pTerrain->IsEmpty()) return false; float fVertexSpacing = pTerrain->GetVertexSpacing(); int nCount = pHeightField->GetGridSize(); float fMinX = x-nCount/2*fVertexSpacing; float fMinY = y-nCount/2*fVertexSpacing; if(bRecoverHeightData) pHeightField->Recover(); for(int i=0;i<nCount;i++) { for(int j=0;j<nCount;j++) { float fVertexX = fMinX + i*fVertexSpacing; float fVertexY = fMinY + j*fVertexSpacing; SetVertexElevation(fVertexX, fVertexY, pHeightField->GetHeight(i,j), false); } } if(bRecalculateGeometry == true) { /** make the region slightly larger. the exact region radius is (nCount-1)*fVertexSpacing/2 */ RecalculateTerrainGeometry(x,y,nCount*fVertexSpacing/2); } return true; }
bool TerrainLattice::Copy_Rect_to_HeightField( TTerrain* pHeightField, float x, float y, float fRadius, bool bNormalize ) { Terrain *pTerrain = GetTerrainAtPoint(x, y); if(pTerrain==NULL || pTerrain->IsEmpty()) return false; float fVertexSpacing = pTerrain->GetVertexSpacing(); int nCount = Math::Round(fRadius/fVertexSpacing)*2+1; float fMinX = x-nCount/2*fVertexSpacing; float fMinY = y-nCount/2*fVertexSpacing; pHeightField->CreatePlane(nCount, 0,fVertexSpacing); for(int i=0;i<nCount;i++) { for(int j=0;j<nCount;j++) { float fVertexX = fMinX + i*fVertexSpacing; float fVertexY = fMinY + j*fVertexSpacing; float fElev = GetVertexElevation(fVertexX, fVertexY); pHeightField->SetHeight(i,j, fElev); } } if(bNormalize) pHeightField->Normalize(); return true; }
void TerrainLattice::MergeHeightField( float x, float y, const char* filename, int mergeOperation/*=0*/, float weight1/*=1.0*/, float weight2/*=1.0*/, int nSmoothPixels/*=7*/ ) { // snap to terrain grid. if(SnapPointToVertexGrid(x,y) == false) return; CTerrainFilters terrafilter; TTerrain* pHeightField = terrafilter.GetTerrainData(); Terrain *pTerrain = GetTerrainAtPoint(x, y); if(pTerrain==NULL || pTerrain->IsEmpty()) return; float fVertexSpacing = pTerrain->GetVertexSpacing(); if(pHeightField->CreatePlane(filename, fVertexSpacing)) { // Set the height to the lowest terrain height in the inner radius terrafilter.SetConstEdgeHeight(0, nSmoothPixels); CTerrainFilters terrafilter2; TTerrain* pHeightFieldCurrent = terrafilter2.GetTerrainData(); if(Copy_Rect_to_HeightField(pHeightFieldCurrent, x,y, (pHeightField->GetGridSize()-1)*fVertexSpacing/2,false) == false) return; terrafilter2.Merge( pHeightFieldCurrent, pHeightField, weight1, weight2, (CTerrainFilters::MergeOperation)mergeOperation); if(Apply_HeightField_to_Rect(pHeightFieldCurrent, x,y,true,true) == false) return; } }
bool TerrainLattice::SnapPointToVertexGrid(float& x, float& y) { Terrain *pTerrain = GetTerrainAtPoint(x, y); if(pTerrain==NULL || pTerrain->IsEmpty()) return false; float fVertexSpacing = pTerrain->GetVertexSpacing(); x = (Math::Round(x / fVertexSpacing))*fVertexSpacing; y = (Math::Round(y / fVertexSpacing))*fVertexSpacing; return true; }
uint32 TerrainLattice::GetTerrainInfo(float x,float y,uint32 bitMask,uint32 bitOffset) { if(SnapPointToVertexGrid(x,y) == false) return 0; if(x<0 || y<0) return 0; int idxX = (int)(x/m_TerrainWidth); int idxY = (int)(y/m_TerrainHeight); Terrain* pTerrain = NULL; pTerrain = GetTerrain(idxX,idxY); if(pTerrain && !(pTerrain->IsEmpty())) { int idx = pTerrain->GetVertexW(x,y); return pTerrain->GetVertexInfo(idx,bitMask, (uint8)bitOffset); } return 0; }
void TerrainLattice::SaveTerrain(bool bHeightMap, bool bTextures) { bool bSaveConfigFile = false; TerrainTileCacheMap_type::iterator itCurCP, itEndCP = m_pCachedTerrains.end(); for( itCurCP = m_pCachedTerrains.begin(); itCurCP != itEndCP; ++ itCurCP) { Terrain* pTerrain = (*itCurCP).second.pTerrain; if(pTerrain->IsModified()) { if(pTerrain->IsEmpty()){ pTerrain->SetModified(false, MODIFIED_ALL); } else { int x,y; pTerrain->GetLatticePosition(x,y); string sConfig = CGlobals::GetWorldInfo()->GetTerrainConfigFile(x,y); if(pTerrain->m_sConfigFile != sConfig) { pTerrain->m_sConfigFile = sConfig; pTerrain->SetModified(true, MODIFIED_CONFIGURATION | MODIFIED_TEXTURE); if (m_pLoader) { m_pLoader->UpdateTileConfigFile(x,y, sConfig); } bSaveConfigFile = true; } pTerrain->SaveToFile(); pTerrain->SetModified(false, MODIFIED_ALL); } } } // save global world config file if any terrain tile is newly created. if(m_bIsGlobalConfigModified || bSaveConfigFile) { if(m_pLoader){ m_pLoader->SaveWorldConfigFile(); } } m_bIsGlobalConfigModified = false; }