| 1552 | } |
| 1553 | |
| 1554 | bool TerrainPatch::ModifySplatMap(int32 index, const Color32* samples, const Int2& modifiedOffset, const Int2& modifiedSize) |
| 1555 | { |
| 1556 | ASSERT(index >= 0 && index < TERRAIN_MAX_SPLATMAPS_COUNT); |
| 1557 | |
| 1558 | // Ensure that terrain has a valid heightmap |
| 1559 | if (Heightmap == nullptr) |
| 1560 | { |
| 1561 | if (InitializeHeightMap() || Heightmap == nullptr) |
| 1562 | { |
| 1563 | LOG(Warning, "Cannot modify splatmap without valid heightmap loaded."); |
| 1564 | return true; |
| 1565 | } |
| 1566 | } |
| 1567 | |
| 1568 | // Validate input samples range |
| 1569 | TerrainDataUpdateInfo info(this, _yOffset, _yHeight); |
| 1570 | if (samples == nullptr) |
| 1571 | { |
| 1572 | LOG(Warning, "Missing splatmap samples data."); |
| 1573 | return true; |
| 1574 | } |
| 1575 | if (modifiedOffset.X < 0 || modifiedOffset.Y < 0 || |
| 1576 | modifiedSize.X <= 0 || modifiedSize.Y <= 0 || |
| 1577 | modifiedOffset.X + modifiedSize.X > info.HeightmapSize || |
| 1578 | modifiedOffset.Y + modifiedSize.Y > info.HeightmapSize) |
| 1579 | { |
| 1580 | LOG(Warning, "Invalid heightmap samples range."); |
| 1581 | return true; |
| 1582 | } |
| 1583 | PROFILE_CPU_NAMED("Terrain.ModifySplatMap"); |
| 1584 | PROFILE_MEM(LevelTerrain); |
| 1585 | |
| 1586 | // Get the current data to modify it |
| 1587 | Color32* splatMap = GetSplatMapData(index); |
| 1588 | if (samples == splatMap) |
| 1589 | { |
| 1590 | LOG(Warning, "Updating terrain with its own data. Oh god xD"); |
| 1591 | } |
| 1592 | |
| 1593 | // Modify splat map data |
| 1594 | { |
| 1595 | PROFILE_CPU_NAMED("Terrain.WrtieCache"); |
| 1596 | for (int32 z = 0; z < modifiedSize.Y; z++) |
| 1597 | { |
| 1598 | // TODO: use batches row mem copy |
| 1599 | |
| 1600 | for (int32 x = 0; x < modifiedSize.X; x++) |
| 1601 | { |
| 1602 | splatMap[(z + modifiedOffset.Y) * info.HeightmapSize + (x + modifiedOffset.X)] = samples[z * modifiedSize.X + x]; |
| 1603 | } |
| 1604 | } |
| 1605 | } |
| 1606 | |
| 1607 | // Initialize data container if need to |
| 1608 | auto& splatmap = Splatmap[index]; |
| 1609 | auto& dataSplatmap = _dataSplatmap[index]; |
| 1610 | if (dataSplatmap == nullptr) |
| 1611 | { |
nothing calls this directly
no test coverage detected