| 1751 | } |
| 1752 | |
| 1753 | bool TerrainPatch::UpdateHeightData(TerrainDataUpdateInfo& info, const Int2& modifiedOffset, const Int2& modifiedSize, bool wasHeightRangeChanged, bool wasHeightChanged) |
| 1754 | { |
| 1755 | PROFILE_CPU(); |
| 1756 | PROFILE_MEM(LevelTerrain); |
| 1757 | float* heightMap = GetHeightmapData(); |
| 1758 | byte* holesMask = GetHolesMaskData(); |
| 1759 | ASSERT(heightMap && holesMask); |
| 1760 | |
| 1761 | // Prepare data for the uploading to GPU |
| 1762 | ASSERT(Heightmap); |
| 1763 | auto texture = Heightmap->GetTexture(); |
| 1764 | ASSERT(texture->IsAllocated()); |
| 1765 | const int32 textureSize = texture->Width(); |
| 1766 | const PixelFormat pixelFormat = texture->Format(); |
| 1767 | const int32 pixelStride = PixelFormatExtensions::SizeInBytes(pixelFormat); |
| 1768 | const int32 lodCount = texture->MipLevels(); |
| 1769 | if (_dataHeightmap == nullptr) |
| 1770 | { |
| 1771 | // Setup |
| 1772 | _dataHeightmap = New<TextureBase::InitData>(); |
| 1773 | _dataHeightmap->Format = pixelFormat; |
| 1774 | _dataHeightmap->Width = textureSize; |
| 1775 | _dataHeightmap->Height = textureSize; |
| 1776 | _dataHeightmap->ArraySize = 1; |
| 1777 | _dataHeightmap->Mips.Resize(lodCount); |
| 1778 | |
| 1779 | // Allocate top level mip |
| 1780 | auto& mip = _dataHeightmap->Mips[0]; |
| 1781 | mip.RowPitch = textureSize * pixelStride; |
| 1782 | mip.SlicePitch = mip.RowPitch * textureSize; |
| 1783 | mip.Data.Allocate(mip.SlicePitch); |
| 1784 | |
| 1785 | // Generate full data on first usage (need to get valid normals and update the whole heightmap region) |
| 1786 | UpdateHeightMap(info, heightMap, mip.Data.Get()); |
| 1787 | UpdateNormalsAndHoles(info, heightMap, holesMask, mip.Data.Get()); |
| 1788 | } |
| 1789 | |
| 1790 | // Downscale mip data for all lower LODs |
| 1791 | if (GenerateMips(_dataHeightmap)) |
| 1792 | return true; |
| 1793 | |
| 1794 | // Fix generated mip maps to keep the same values for chunk edges (reduce cracks on continuous LOD transitions) |
| 1795 | FixMips(info, _dataHeightmap, pixelStride); |
| 1796 | |
| 1797 | // Update terrain texture (on a GPU) |
| 1798 | for (int32 mipIndex = 0; mipIndex < _dataHeightmap->Mips.Count(); mipIndex++) |
| 1799 | { |
| 1800 | auto task = texture->UploadMipMapAsync(_dataHeightmap->Mips[mipIndex].Data, mipIndex); |
| 1801 | if (task) |
| 1802 | task->Start(); |
| 1803 | } |
| 1804 | |
| 1805 | #if 1 |
| 1806 | if (wasHeightRangeChanged) |
| 1807 | { |
| 1808 | // When min-max height range has been changed for the patch let's update it all, it's faster to cook collision and rebuild shape rather than modify all the samples |
| 1809 | if (_heightfield->WaitForLoaded()) |
| 1810 | { |
nothing calls this directly
no test coverage detected