| 1867 | } |
| 1868 | |
| 1869 | void TerrainPatch::SaveHeightData() |
| 1870 | { |
| 1871 | #if USE_EDITOR |
| 1872 | // Skip if was not modified or cannot be saved |
| 1873 | if (!_wasHeightModified || |
| 1874 | Heightmap == nullptr || |
| 1875 | _heightfield == nullptr || |
| 1876 | Heightmap->IsVirtual() || |
| 1877 | _heightfield->IsVirtual() || |
| 1878 | _dataHeightmap == nullptr) |
| 1879 | { |
| 1880 | return; |
| 1881 | } |
| 1882 | PROFILE_CPU_NAMED("Terrain.Save"); |
| 1883 | TerrainDataUpdateInfo info(this, _yOffset, _yHeight); |
| 1884 | |
| 1885 | // Save heightmap to asset |
| 1886 | if (Heightmap->WaitForLoaded()) |
| 1887 | { |
| 1888 | LOG(Error, "Failed to load patch heightmap data."); |
| 1889 | return; |
| 1890 | } |
| 1891 | if (Heightmap->Save(String::Empty, _dataHeightmap)) |
| 1892 | { |
| 1893 | LOG(Error, "Failed to save heightmap data to asset."); |
| 1894 | return; |
| 1895 | } |
| 1896 | |
| 1897 | // Generate physics backend height field data for the runtime |
| 1898 | if (_heightfield->WaitForLoaded()) |
| 1899 | { |
| 1900 | LOG(Error, "Failed to load patch heightfield data."); |
| 1901 | return; |
| 1902 | } |
| 1903 | const auto collisionData = &_heightfield->Data; |
| 1904 | if (CookCollision(info, _dataHeightmap, _terrain->_collisionLod, collisionData)) |
| 1905 | { |
| 1906 | return; |
| 1907 | } |
| 1908 | |
| 1909 | // Save heightfield to asset |
| 1910 | if (_heightfield->Save()) |
| 1911 | { |
| 1912 | LOG(Error, "Failed to save heightfield data to asset."); |
| 1913 | return; |
| 1914 | } |
| 1915 | |
| 1916 | // Clear flag |
| 1917 | _wasHeightModified = false; |
| 1918 | #endif |
| 1919 | } |
| 1920 | |
| 1921 | void TerrainPatch::SaveSplatData() |
| 1922 | { |
nothing calls this directly
no test coverage detected