| 564 | } |
| 565 | |
| 566 | void FixMips(const TerrainDataUpdateInfo& info, TextureBase::InitData* initData, int32 pixelStride) |
| 567 | { |
| 568 | PROFILE_CPU_NAMED("Terrain.FixMips"); |
| 569 | |
| 570 | for (int32 mipIndex = 1; mipIndex < initData->Mips.Count(); mipIndex++) |
| 571 | { |
| 572 | auto& mip = initData->Mips[mipIndex]; |
| 573 | auto& mipHigher = initData->Mips[mipIndex - 1]; |
| 574 | byte* mipData = mip.Data.Get(); |
| 575 | const byte* mipDataHigher = mipHigher.Data.Get(); |
| 576 | const int32 vertexCountEdgeMip = info.VertexCountEdge >> mipIndex; |
| 577 | const int32 textureSizeMip = info.TextureSize >> mipIndex; |
| 578 | const int32 vertexCountEdgeMipHigher = vertexCountEdgeMip << 1; |
| 579 | const int32 textureSizeMipHigher = textureSizeMip << 1; |
| 580 | |
| 581 | // Make heightmap values on left edge the same as the left edge of the chunk on the higher LOD |
| 582 | for (int32 chunkX = 0; chunkX < Terrain::ChunksCountEdge; chunkX++) |
| 583 | { |
| 584 | for (int32 chunkZ = 0; chunkZ < Terrain::ChunksCountEdge; chunkZ++) |
| 585 | { |
| 586 | const int32 chunkTextureX = chunkX * vertexCountEdgeMip; |
| 587 | const int32 chunkTextureZ = chunkZ * vertexCountEdgeMip; |
| 588 | |
| 589 | const int32 chunkTextureXHigher = chunkX * vertexCountEdgeMipHigher; |
| 590 | const int32 chunkTextureZHigher = chunkZ * vertexCountEdgeMipHigher; |
| 591 | |
| 592 | // Exclude patch edges |
| 593 | int32 z = 0, zCount = vertexCountEdgeMip; |
| 594 | int32 x = 0, xCount = vertexCountEdgeMip; |
| 595 | if (chunkX == 0) |
| 596 | x = 1; |
| 597 | else if (chunkX == Terrain::ChunksCountEdge - 1) |
| 598 | xCount--; |
| 599 | if (chunkZ == 0) |
| 600 | z = 1; |
| 601 | else if (chunkZ == Terrain::ChunksCountEdge - 1) |
| 602 | zCount--; |
| 603 | |
| 604 | for (; z < zCount; z++) |
| 605 | { |
| 606 | const int32 textureIndex = (chunkTextureZ + z) * textureSizeMip + chunkTextureX; |
| 607 | |
| 608 | const int32 zHigher = (int32)(((float)z / vertexCountEdgeMip) * vertexCountEdgeMipHigher); |
| 609 | const int32 textureIndexHigherMip = (chunkTextureZHigher + zHigher) * textureSizeMipHigher + chunkTextureXHigher; |
| 610 | const byte* higherMipData = mipDataHigher + textureIndexHigherMip * pixelStride; |
| 611 | |
| 612 | Platform::MemoryCopy(mipData + textureIndex * pixelStride, higherMipData, pixelStride); |
| 613 | } |
| 614 | |
| 615 | for (; x < xCount; x++) |
| 616 | { |
| 617 | const int32 textureIndex = chunkTextureZ * textureSizeMip + chunkTextureX + x; |
| 618 | |
| 619 | const int32 xHigher = (int32)(((float)x / vertexCountEdgeMip) * vertexCountEdgeMipHigher); |
| 620 | const int32 textureIndexHigherMip = chunkTextureZHigher * textureSizeMipHigher + chunkTextureXHigher + xHigher; |
| 621 | const byte* higherMipData = mipDataHigher + textureIndexHigherMip * pixelStride; |
| 622 | |
| 623 | Platform::MemoryCopy(mipData + textureIndex * pixelStride, higherMipData, pixelStride); |
no test coverage detected