| 1251 | } |
| 1252 | |
| 1253 | void TerrainPatch::CacheHeightData() |
| 1254 | { |
| 1255 | if (Heightmap == nullptr) |
| 1256 | { |
| 1257 | LOG(Error, "Missing heightmap."); |
| 1258 | return; |
| 1259 | } |
| 1260 | PROFILE_CPU_NAMED("Terrain.CacheHeightData"); |
| 1261 | PROFILE_MEM(LevelTerrain); |
| 1262 | const TerrainDataUpdateInfo info(this); |
| 1263 | |
| 1264 | // Ensure that heightmap data is all loaded |
| 1265 | // TODO: disable streaming for heightmap texture if it's being modified by the editor |
| 1266 | if (Heightmap->WaitForLoaded()) |
| 1267 | { |
| 1268 | LOG(Error, "Failed to load patch heightmap data."); |
| 1269 | return; |
| 1270 | } |
| 1271 | |
| 1272 | // Get the LOD0 mip map data and extract the heightmap |
| 1273 | auto lock = Heightmap->LockData(); |
| 1274 | BytesContainer mipLOD0; |
| 1275 | Heightmap->GetMipDataWithLoading(0, mipLOD0); |
| 1276 | if (mipLOD0.IsInvalid()) |
| 1277 | { |
| 1278 | LOG(Error, "Failed to get patch heightmap data."); |
| 1279 | return; |
| 1280 | } |
| 1281 | |
| 1282 | // Allocate data |
| 1283 | _cachedHeightMap.Resize(info.HeightmapLength); |
| 1284 | _cachedHolesMask.Resize(info.HeightmapLength); |
| 1285 | _wasHeightModified = false; |
| 1286 | |
| 1287 | // Extract heightmap data and denormalize it to get the pure height field |
| 1288 | const float patchOffset = _yOffset; |
| 1289 | const float patchHeight = _yHeight; |
| 1290 | const auto heightmapPtr = _cachedHeightMap.Get(); |
| 1291 | const auto holesMaskPtr = _cachedHolesMask.Get(); |
| 1292 | for (int32 chunkIndex = 0; chunkIndex < Terrain::ChunksCount; chunkIndex++) |
| 1293 | { |
| 1294 | const int32 chunkTextureX = Chunks[chunkIndex]._x * info.VertexCountEdge; |
| 1295 | const int32 chunkTextureZ = Chunks[chunkIndex]._z * info.VertexCountEdge; |
| 1296 | |
| 1297 | const int32 chunkHeightmapX = Chunks[chunkIndex]._x * info.ChunkSize; |
| 1298 | const int32 chunkHeightmapZ = Chunks[chunkIndex]._z * info.ChunkSize; |
| 1299 | |
| 1300 | for (int32 z = 0; z < info.VertexCountEdge; z++) |
| 1301 | { |
| 1302 | const int32 tz = (chunkTextureZ + z) * info.TextureSize; |
| 1303 | const int32 sz = (chunkHeightmapZ + z) * info.HeightmapSize; |
| 1304 | |
| 1305 | for (int32 x = 0; x < info.VertexCountEdge; x++) |
| 1306 | { |
| 1307 | const int32 tx = chunkTextureX + x; |
| 1308 | const int32 sx = chunkHeightmapX + x; |
| 1309 | const int32 textureIndex = tz + tx; |
| 1310 | const int32 heightmapIndex = sz + sx; |
nothing calls this directly
no test coverage detected