Index: ps/trunk/source/simulation2/components/CCmpPathfinder.cpp =================================================================== --- ps/trunk/source/simulation2/components/CCmpPathfinder.cpp +++ ps/trunk/source/simulation2/components/CCmpPathfinder.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Wildfire Games. +/* Copyright (C) 2020 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -177,9 +177,12 @@ break; } case MT_TerrainChanged: + { + const CMessageTerrainChanged& msgData = static_cast(msg); m_TerrainDirty = true; - MinimalTerrainUpdate(); + MinimalTerrainUpdate(msgData.i0, msgData.j0, msgData.i1, msgData.j1); break; + } case MT_WaterChanged: case MT_ObstructionMapShapeChanged: m_TerrainDirty = true; @@ -564,12 +567,12 @@ m_AIPathfinderDirtinessInformation.MergeAndClear(m_DirtinessInformation); } -void CCmpPathfinder::MinimalTerrainUpdate() +void CCmpPathfinder::MinimalTerrainUpdate(int itile0, int jtile0, int itile1, int jtile1) { - TerrainUpdateHelper(false); + TerrainUpdateHelper(false, itile0, jtile0, itile1, jtile1); } -void CCmpPathfinder::TerrainUpdateHelper(bool expandPassability/* = true */) +void CCmpPathfinder::TerrainUpdateHelper(bool expandPassability, int itile0, int jtile0, int itile1, int jtile1) { PROFILE3("TerrainUpdateHelper"); @@ -585,7 +588,8 @@ if (terrainSize == 0) return; - if (!m_TerrainOnlyGrid || m_MapSize != terrainSize) + const bool needsNewTerrainGrid = !m_TerrainOnlyGrid || m_MapSize != terrainSize; + if (needsNewTerrainGrid) { m_MapSize = terrainSize; @@ -605,10 +609,26 @@ Grid shoreGrid = ComputeShoreGrid(); + const bool partialTerrainGridUpdate = + !expandPassability && !needsNewTerrainGrid && + itile0 != -1 && jtile0 != -1 && itile1 != -1 && jtile1 != -1; + int istart = 0, iend = m_MapSize * Pathfinding::NAVCELLS_PER_TILE; + int jstart = 0, jend = m_MapSize * Pathfinding::NAVCELLS_PER_TILE; + if (partialTerrainGridUpdate) + { + // We need to extend the boundaries by 1 tile, because slope and ground + // level are calculated by multiple neighboring tiles. + // TODO: add CTerrain constant instead of 1. + istart = Clamp(itile0 - 1, 0, static_cast(m_MapSize)) * Pathfinding::NAVCELLS_PER_TILE; + iend = Clamp(itile1 + 1, 0, static_cast(m_MapSize)) * Pathfinding::NAVCELLS_PER_TILE; + jstart = Clamp(jtile0 - 1, 0, static_cast(m_MapSize)) * Pathfinding::NAVCELLS_PER_TILE; + jend = Clamp(jtile1 + 1, 0, static_cast(m_MapSize)) * Pathfinding::NAVCELLS_PER_TILE; + } + // Compute initial terrain-dependent passability - for (int j = 0; j < m_MapSize * Pathfinding::NAVCELLS_PER_TILE; ++j) + for (int j = jstart; j < jend; ++j) { - for (int i = 0; i < m_MapSize * Pathfinding::NAVCELLS_PER_TILE; ++i) + for (int i = istart; i < iend; ++i) { // World-space coordinates for this navcell fixed x, z; @@ -656,9 +676,9 @@ if (cmpObstructionManager->GetPassabilityCircular()) { - for (int j = 0; j < h; ++j) + for (int j = jstart; j < jend; ++j) { - for (int i = 0; i < w; ++i) + for (int i = istart; i < iend; ++i) { // Based on CCmpRangeManager::LosIsOffWorld // but tweaked since it's tile-based instead. Index: ps/trunk/source/simulation2/components/CCmpPathfinder_Common.h =================================================================== --- ps/trunk/source/simulation2/components/CCmpPathfinder_Common.h +++ ps/trunk/source/simulation2/components/CCmpPathfinder_Common.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Wildfire Games. +/* Copyright (C) 2020 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -240,13 +240,13 @@ * Updates the terrain-only grid without updating the dirtiness informations. * Useful for fast passability updates in Atlas. */ - void MinimalTerrainUpdate(); + void MinimalTerrainUpdate(int itile0, int jtile0, int itile1, int jtile1); /** * Regenerates the terrain-only grid. * Atlas doesn't need to have passability cells expanded. */ - void TerrainUpdateHelper(bool expandPassability = true); + void TerrainUpdateHelper(bool expandPassability = true, int itile0 = -1, int jtile0 = -1, int itile1 = -1, int jtile1 = -1); void RenderSubmit(SceneCollector& collector); };