Ticket #3588: InitRegions.patch

File InitRegions.patch, 2.2 KB (added by fsincos, 8 years ago)
  • source/simulation2/helpers/HierarchicalPathfinder.cpp

    diff --git a/source/simulation2/helpers/HierarchicalPathfinder.cpp b/source/simulation2/helpers/HierarchicalPathfinder.cpp
    index 8ccbb02..ad1b3e9 100644
    a b  
    1 /* Copyright (C) 2015 Wildfire Games.
     1/* Copyright (C) 2016 Wildfire Games.
    22 * This file is part of 0 A.D.
    33 *
    44 * 0 A.D. is free software: you can redistribute it and/or modify
     
    2525// Find the root ID of a region, used by InitRegions
    2626inline u16 RootID(u16 x, const std::vector<u16>& v)
    2727{
    28     // Just add a basic check for infinite loops
    29     int checkLoop = 0;
    3028    while (v[x] < x)
    31     {
    32         ++checkLoop;
    33         ENSURE(checkLoop < 1000 && "Long loop (probably infinite), unable to find an invariant point");
    3429        x = v[x];
    35     }
    3630
    3731    return x;
    3832}
    void HierarchicalPathfinder::Chunk::InitRegions(int ci, int cj, Grid<NavcellData  
    5852    u16* pCurrentID = NULL;
    5953    u16 LeftID = 0;
    6054    u16 DownID = 0;
     55    bool Checked = false; // prevent some unneccessary RootID calls
    6156
    6257    connect.reserve(32); // TODO: What's a sensible number?
    6358    connect.push_back(0); // connect[0] = 0
    void HierarchicalPathfinder::Chunk::InitRegions(int ci, int cj, Grid<NavcellData  
    8681            if (LeftID > 0)
    8782            {
    8883                *pCurrentID = LeftID;
    89                 if (*pCurrentID != DownID && DownID > 0)
     84                if (*pCurrentID != DownID && DownID > 0 && !Checked)
    9085                {
    9186                    u16 id0 = RootID(DownID, connect);
    9287                    u16 id1 = RootID(LeftID, connect);
     88                    Checked = true; // this avoids repeatedly connecting the same IDs
    9389
    9490                    if (id0 < id1)
    9591                        connect[id1] = id0;
    9692                    else if (id0 > id1)
    9793                        connect[id0] = id1;
    9894                }
     95                else if (DownID == 0)
     96                    Checked = false;
    9997            }
    10098            else if (DownID > 0)
     99            {
    101100                *pCurrentID = DownID;
     101                Checked = false;
     102            }
    102103            else
    103104            {
    104105                // New ID
    105106                *pCurrentID = ++regionID;
    106107                connect.push_back(regionID);
     108                Checked = false;
    107109            }
    108110        }
    109111    }
    110112
    111113    // Directly point the root ID
    112114    m_NumRegions = 0;
    113     for (u16 i = regionID; i > 0; --i)
     115    for (u16 i = 1; i <= regionID; ++i)
    114116    {
    115117        if (connect[i] == i)
    116118            ++m_NumRegions;
    117119        else
    118             connect[i] = RootID(i,connect);
     120            connect[i] = connect[connect[i]]; // = RootID(i,connect) by induction
    119121    }
    120122
    121123    // Replace IDs by the root ID