Ticket #3588: Cleanup1.patch

File Cleanup1.patch, 11.5 KB (added by fsincos, 8 years ago)
  • source/maths/FixedVector2D.h

    diff --git a/source/maths/FixedVector2D.h b/source/maths/FixedVector2D.h
    index d2728f4..37fd1fd 100644
    a b public:  
    212212        return ret;
    213213    }
    214214
     215    // Is u.Dot(v.Perpendicular()) > 0 ? Avoid overflows, shifts, etc.
     216    bool CrossGTZero(const CFixedVector2D& v) const
     217    {
     218        return (FIXED_MUL_I64_I32_I32(X.GetInternalValue(), v.Y.GetInternalValue()) > FIXED_MUL_I64_I32_I32(Y.GetInternalValue(), v.X.GetInternalValue()));
     219    }
     220
    215221    CFixedVector2D Perpendicular() const
    216222    {
    217223        return CFixedVector2D(Y, -X);
  • source/simulation2/components/CCmpPathfinder_Vertex.cpp

    diff --git a/source/simulation2/components/CCmpPathfinder_Vertex.cpp b/source/simulation2/components/CCmpPathfinder_Vertex.cpp
    index 5ab11b6..5af5ce4 100644
    a b static const entity_pos_t EDGE_EXPAND_DELTA = entity_pos_t::FromInt(1)/16;  
    135135 */
    136136inline static bool CheckVisibility(const CFixedVector2D& a, const CFixedVector2D& b, const std::vector<Edge>& edges)
    137137{
    138     CFixedVector2D abn = (b - a).Perpendicular();
     138    CFixedVector2D ab = b - a;
    139139
    140140    // Edges of general non-axis-aligned shapes
    141141    for (size_t i = 0; i < edges.size(); ++i)
    inline static bool CheckVisibility(const CFixedVector2D& a, const CFixedVector2D  
    143143        CFixedVector2D p0 = edges[i].p0;
    144144        CFixedVector2D p1 = edges[i].p1;
    145145
    146         CFixedVector2D d = (p1 - p0).Perpendicular();
     146        CFixedVector2D d = p1 - p0;
    147147
    148148        // If 'a' is behind the edge, we can't cross
    149         fixed q = (a - p0).Dot(d);
    150         if (q < fixed::Zero())
     149        if ((p0 - a).CrossGTZero(d))
    151150            continue;
    152151
    153152        // If 'b' is in front of the edge, we can't cross
    154         fixed r = (b - p0).Dot(d);
    155         if (r > fixed::Zero())
     153        if ((b - p0).CrossGTZero(d))
    156154            continue;
    157155
    158156        // The ray is crossing the infinitely-extended edge from in front to behind.
    159157        // Check the finite edge is crossing the infinitely-extended ray too.
    160158        // (Given the previous tests, it can only be crossing in one direction.)
    161         fixed s = (p0 - a).Dot(abn);
    162         if (s > fixed::Zero())
     159        if ((p0 - a).CrossGTZero(ab))
    163160            continue;
    164161
    165         fixed t = (p1 - a).Dot(abn);
    166         if (t < fixed::Zero())
     162        if ((a - p1).CrossGTZero(ab))
    167163            continue;
    168164
    169165        return false;
    inline static bool CheckVisibilityLeft(const CFixedVector2D& a, const CFixedVect  
    182178    if (a.X >= b.X)
    183179        return true;
    184180
    185     CFixedVector2D abn = (b - a).Perpendicular();
     181    CFixedVector2D ab = b - a;
    186182
    187183    for (size_t i = 0; i < edges.size(); ++i)
    188184    {
    inline static bool CheckVisibilityLeft(const CFixedVector2D& a, const CFixedVect  
    190186            continue;
    191187
    192188        CFixedVector2D p0 (edges[i].p0.X, edges[i].c1);
    193         fixed s = (p0 - a).Dot(abn);
    194         if (s > fixed::Zero())
     189        if ((p0 - a).CrossGTZero(ab))
    195190            continue;
    196191
    197192        CFixedVector2D p1 (edges[i].p0.X, edges[i].p0.Y);
    198         fixed t = (p1 - a).Dot(abn);
    199         if (t < fixed::Zero())
     193        if ((a - p1).CrossGTZero(ab))
    200194            continue;
    201195
    202196        return false;
    inline static bool CheckVisibilityRight(const CFixedVector2D& a, const CFixedVec  
    210204    if (a.X <= b.X)
    211205        return true;
    212206
    213     CFixedVector2D abn = (b - a).Perpendicular();
     207    CFixedVector2D ab = b - a;
    214208
    215209    for (size_t i = 0; i < edges.size(); ++i)
    216210    {
    inline static bool CheckVisibilityRight(const CFixedVector2D& a, const CFixedVec  
    218212            continue;
    219213
    220214        CFixedVector2D p0 (edges[i].p0.X, edges[i].c1);
    221         fixed s = (p0 - a).Dot(abn);
    222         if (s > fixed::Zero())
     215        if ((p0 - a).CrossGTZero(ab))
    223216            continue;
    224217
    225218        CFixedVector2D p1 (edges[i].p0.X, edges[i].p0.Y);
    226         fixed t = (p1 - a).Dot(abn);
    227         if (t < fixed::Zero())
     219        if ((a - p1).CrossGTZero(ab))
    228220            continue;
    229221
    230222        return false;
    inline static bool CheckVisibilityBottom(const CFixedVector2D& a, const CFixedVe  
    238230    if (a.Y >= b.Y)
    239231        return true;
    240232
    241     CFixedVector2D abn = (b - a).Perpendicular();
     233    CFixedVector2D ab = b - a;
    242234
    243235    for (size_t i = 0; i < edges.size(); ++i)
    244236    {
    inline static bool CheckVisibilityBottom(const CFixedVector2D& a, const CFixedVe  
    246238            continue;
    247239
    248240        CFixedVector2D p0 (edges[i].p0.X, edges[i].p0.Y);
    249         fixed s = (p0 - a).Dot(abn);
    250         if (s > fixed::Zero())
     241        if ((p0 - a).CrossGTZero(ab))
    251242            continue;
    252243
    253244        CFixedVector2D p1 (edges[i].c1, edges[i].p0.Y);
    254         fixed t = (p1 - a).Dot(abn);
    255         if (t < fixed::Zero())
     245        if ((a - p1).CrossGTZero(ab))
    256246            continue;
    257247
    258248        return false;
    inline static bool CheckVisibilityTop(const CFixedVector2D& a, const CFixedVecto  
    266256    if (a.Y <= b.Y)
    267257        return true;
    268258
    269     CFixedVector2D abn = (b - a).Perpendicular();
     259    CFixedVector2D ab = b - a;
    270260
    271261    for (size_t i = 0; i < edges.size(); ++i)
    272262    {
    inline static bool CheckVisibilityTop(const CFixedVector2D& a, const CFixedVecto  
    274264            continue;
    275265
    276266        CFixedVector2D p0 (edges[i].p0.X, edges[i].p0.Y);
    277         fixed s = (p0 - a).Dot(abn);
    278         if (s > fixed::Zero())
     267        if ((p0 - a).CrossGTZero(ab))
    279268            continue;
    280269
    281270        CFixedVector2D p1 (edges[i].c1, edges[i].p0.Y);
    282         fixed t = (p1 - a).Dot(abn);
    283         if (t < fixed::Zero())
     271        if ((a - p1).CrossGTZero(ab))
    284272            continue;
    285273
    286274        return false;
    static void AddTerrainEdges(std::vector<Edge>& edges, std::vector<Vertex>& verte  
    360348            }
    361349        }
    362350    }
    363 
    364     // XXX rewrite this stuff
    365 
    366351    for (int j = j0; j < j1; ++j)
    367352    {
    368         std::vector<u16> segmentsR;
    369         std::vector<u16> segmentsL;
     353        bool leftEdge = false, rightEdge = false;
     354        int iStartL = 0, iStartR = 0;
    370355
    371356        for (int i = i0; i <= i1; ++i)
    372357        {
    373358            bool a = IS_PASSABLE(grid.get(i, j+1), passClass);
    374359            bool b = IS_PASSABLE(grid.get(i, j), passClass);
    375             if (a && !b)
    376                 segmentsL.push_back(i);
    377             if (b && !a)
    378                 segmentsR.push_back(i);
    379         }
    380360
    381         if (!segmentsR.empty())
    382         {
    383             segmentsR.push_back(0); // sentinel value to simplify the loop
    384             u16 ia = segmentsR[0];
    385             u16 ib = ia + 1;
    386             for (size_t n = 1; n < segmentsR.size(); ++n)
     361            if ((b || !a) && leftEdge) // left edge ends here
    387362            {
    388                 if (segmentsR[n] == ib)
    389                     ++ib;
    390                 else
    391                 {
    392                     CFixedVector2D v0 = CFixedVector2D(fixed::FromInt(ia), fixed::FromInt(j+1)).Multiply(Pathfinding::NAVCELL_SIZE);
    393                     CFixedVector2D v1 = CFixedVector2D(fixed::FromInt(ib), fixed::FromInt(j+1)).Multiply(Pathfinding::NAVCELL_SIZE);
    394                     edges.emplace_back(Edge{ v0, v1 });
    395 
    396                     ia = segmentsR[n];
    397                     ib = ia + 1;
    398                 }
     363                CFixedVector2D v0 = CFixedVector2D(fixed::FromInt(i), fixed::FromInt(j+1)).Multiply(Pathfinding::NAVCELL_SIZE);
     364                CFixedVector2D v1 = CFixedVector2D(fixed::FromInt(iStartL), fixed::FromInt(j+1)).Multiply(Pathfinding::NAVCELL_SIZE);
     365                edges.emplace_back(Edge{ v0, v1 });
     366                leftEdge = false;
    399367            }
    400         }
    401 
    402         if (!segmentsL.empty())
    403         {
    404             segmentsL.push_back(0); // sentinel value to simplify the loop
    405             u16 ia = segmentsL[0];
    406             u16 ib = ia + 1;
    407             for (size_t n = 1; n < segmentsL.size(); ++n)
     368            else if (a && !b && !leftEdge) // left edge begins here
    408369            {
    409                 if (segmentsL[n] == ib)
    410                     ++ib;
    411                 else
    412                 {
    413                     CFixedVector2D v0 = CFixedVector2D(fixed::FromInt(ib), fixed::FromInt(j+1)).Multiply(Pathfinding::NAVCELL_SIZE);
    414                     CFixedVector2D v1 = CFixedVector2D(fixed::FromInt(ia), fixed::FromInt(j+1)).Multiply(Pathfinding::NAVCELL_SIZE);
    415                     edges.emplace_back(Edge{ v0, v1 });
     370                iStartL = i;
     371                leftEdge = true;
     372            }
    416373
    417                     ia = segmentsL[n];
    418                     ib = ia + 1;
    419                 }
     374            if ((a || !b) && rightEdge) // right edge ends here
     375            {
     376                CFixedVector2D v0 = CFixedVector2D(fixed::FromInt(iStartR), fixed::FromInt(j+1)).Multiply(Pathfinding::NAVCELL_SIZE);
     377                CFixedVector2D v1 = CFixedVector2D(fixed::FromInt(i), fixed::FromInt(j+1)).Multiply(Pathfinding::NAVCELL_SIZE);
     378                edges.emplace_back(Edge{ v0, v1 });
     379                rightEdge = false;
     380            }
     381            else if (b && !a && !rightEdge) // right edge begins here
     382            {
     383                iStartR = i;
     384                rightEdge = true;
    420385            }
    421386        }
     387        if (leftEdge) // end remaining edges
     388        {
     389            CFixedVector2D v0 = CFixedVector2D(fixed::FromInt(i1+1), fixed::FromInt(j+1)).Multiply(Pathfinding::NAVCELL_SIZE);
     390            CFixedVector2D v1 = CFixedVector2D(fixed::FromInt(iStartL), fixed::FromInt(j+1)).Multiply(Pathfinding::NAVCELL_SIZE);
     391            edges.emplace_back(Edge{ v0, v1 });
     392        }
     393        if (rightEdge)
     394        {
     395            CFixedVector2D v0 = CFixedVector2D(fixed::FromInt(iStartR), fixed::FromInt(j+1)).Multiply(Pathfinding::NAVCELL_SIZE);
     396            CFixedVector2D v1 = CFixedVector2D(fixed::FromInt(i1+1), fixed::FromInt(j+1)).Multiply(Pathfinding::NAVCELL_SIZE);
     397            edges.emplace_back(Edge{ v0, v1 });
     398        }
    422399    }
    423 
    424400    for (int i = i0; i < i1; ++i)
    425401    {
    426         std::vector<u16> segmentsU;
    427         std::vector<u16> segmentsD;
     402        bool topEdge = false, bottomEdge = false;
     403        int jStartT = 0, jStartB = 0;
    428404
    429405        for (int j = j0; j <= j1; ++j)
    430406        {
    431407            bool a = IS_PASSABLE(grid.get(i+1, j), passClass);
    432408            bool b = IS_PASSABLE(grid.get(i, j), passClass);
    433             if (a && !b)
    434                 segmentsU.push_back(j);
    435             if (b && !a)
    436                 segmentsD.push_back(j);
    437         }
    438409
    439         if (!segmentsU.empty())
    440         {
    441             segmentsU.push_back(0); // sentinel value to simplify the loop
    442             u16 ja = segmentsU[0];
    443             u16 jb = ja + 1;
    444             for (size_t n = 1; n < segmentsU.size(); ++n)
     410            if ((b || !a) && bottomEdge) // bottom edge ends here
    445411            {
    446                 if (segmentsU[n] == jb)
    447                     ++jb;
    448                 else
    449                 {
    450                     CFixedVector2D v0 = CFixedVector2D(fixed::FromInt(i+1), fixed::FromInt(ja)).Multiply(Pathfinding::NAVCELL_SIZE);
    451                     CFixedVector2D v1 = CFixedVector2D(fixed::FromInt(i+1), fixed::FromInt(jb)).Multiply(Pathfinding::NAVCELL_SIZE);
    452                     edges.emplace_back(Edge{ v0, v1 });
    453 
    454                     ja = segmentsU[n];
    455                     jb = ja + 1;
    456                 }
     412                CFixedVector2D v0 = CFixedVector2D(fixed::FromInt(i+1), fixed::FromInt(j)).Multiply(Pathfinding::NAVCELL_SIZE);
     413                CFixedVector2D v1 = CFixedVector2D(fixed::FromInt(i+1), fixed::FromInt(jStartB)).Multiply(Pathfinding::NAVCELL_SIZE);
     414                edges.emplace_back(Edge{ v0, v1 });
     415                bottomEdge = false;
    457416            }
    458         }
    459 
    460         if (!segmentsD.empty())
    461         {
    462             segmentsD.push_back(0); // sentinel value to simplify the loop
    463             u16 ja = segmentsD[0];
    464             u16 jb = ja + 1;
    465             for (size_t n = 1; n < segmentsD.size(); ++n)
     417            else if (a && !b && !bottomEdge) // bottom edge begins here
    466418            {
    467                 if (segmentsD[n] == jb)
    468                     ++jb;
    469                 else
    470                 {
    471                     CFixedVector2D v0 = CFixedVector2D(fixed::FromInt(i+1), fixed::FromInt(jb)).Multiply(Pathfinding::NAVCELL_SIZE);
    472                     CFixedVector2D v1 = CFixedVector2D(fixed::FromInt(i+1), fixed::FromInt(ja)).Multiply(Pathfinding::NAVCELL_SIZE);
    473                     edges.emplace_back(Edge{ v0, v1 });
     419                jStartB = i;
     420                bottomEdge = true;
     421            }
    474422
    475                     ja = segmentsD[n];
    476                     jb = ja + 1;
    477                 }
     423            if ((a || !b) && topEdge) // top edge ends here
     424            {
     425                CFixedVector2D v0 = CFixedVector2D(fixed::FromInt(i+1), fixed::FromInt(jStartT)).Multiply(Pathfinding::NAVCELL_SIZE);
     426                CFixedVector2D v1 = CFixedVector2D(fixed::FromInt(i+1), fixed::FromInt(j)).Multiply(Pathfinding::NAVCELL_SIZE);
     427                edges.emplace_back(Edge{ v0, v1 });
     428                topEdge = false;
     429            }
     430            else if (b && !a && !topEdge) // top edge begins here
     431            {
     432                jStartT = i;
     433                topEdge = true;
    478434            }
    479435        }
     436        if (bottomEdge) // end remaining edges
     437        {
     438            CFixedVector2D v0 = CFixedVector2D(fixed::FromInt(i+1), fixed::FromInt(j1+1)).Multiply(Pathfinding::NAVCELL_SIZE);
     439            CFixedVector2D v1 = CFixedVector2D(fixed::FromInt(i+1), fixed::FromInt(jStartB)).Multiply(Pathfinding::NAVCELL_SIZE);
     440            edges.emplace_back(Edge{ v0, v1 });
     441        }
     442        if (topEdge)
     443        {
     444            CFixedVector2D v0 = CFixedVector2D(fixed::FromInt(i+1), fixed::FromInt(jStartT)).Multiply(Pathfinding::NAVCELL_SIZE);
     445            CFixedVector2D v1 = CFixedVector2D(fixed::FromInt(i+1), fixed::FromInt(j1+1)).Multiply(Pathfinding::NAVCELL_SIZE);
     446            edges.emplace_back(Edge{ v0, v1 });
     447        }
    480448    }
    481449}
    482450