Guest User

Untitled

a guest
Mar 20th, 2017
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.92 KB | None | 0 0
  1. void Units::generateLOSLineSegments(Unit* unit, sf::VertexArray* vertices)
  2. {
  3.     vector<f2> linesFinal; 
  4.     f2 position = unit->offCenter();
  5.     f2 textureCenter = VALUES.getf2("visionCircleCenter");
  6.     f2 center = unit->offCenter();
  7.  
  8.     for (auto const& element : walls_)
  9.     {
  10.         Wall* wall = element.second;
  11.         if (!wall->canBeSeenThrough_)
  12.         {
  13.             if (wall->contains(position))
  14.             {
  15.                 vertices->append(sf::Vertex(center, textureCenter));
  16.                 vertices->append(sf::Vertex(wall->topLeft(), textureCenter + f2(50, 0)));
  17.                 vertices->append(sf::Vertex(wall->topRight(), textureCenter + f2(0, 50)));
  18.                 vertices->append(sf::Vertex(center, textureCenter));
  19.                 vertices->append(sf::Vertex(wall->topLeft(), textureCenter + f2(50, 0)));
  20.                 vertices->append(sf::Vertex(wall->bottomLeft(), textureCenter + f2(0, 50)));
  21.                 vertices->append(sf::Vertex(center, textureCenter));
  22.                 vertices->append(sf::Vertex(wall->bottomRight(), textureCenter + f2(50, 0)));
  23.                 vertices->append(sf::Vertex(wall->topRight(), textureCenter + f2(0, 50)));
  24.                 vertices->append(sf::Vertex(center, textureCenter));
  25.                 vertices->append(sf::Vertex(wall->bottomLeft(), textureCenter + f2(50, 0)));
  26.                 vertices->append(sf::Vertex(wall->bottomRight(), textureCenter + f2(0, 50)));
  27.                 return;
  28.             }
  29.             vector<vector<float>> lines = {{wall->topLeft().x, wall->topLeft().y, wall->topRight().x, wall->topRight().y},
  30.                                                                          {wall->topLeft().x, wall->topLeft().y, wall->bottomLeft().x, wall->bottomLeft().y},
  31.                                                                          {wall->bottomRight().x, wall->bottomRight().y, wall->bottomLeft().x, wall->bottomLeft().y},
  32.                                                                          {wall->bottomRight().x, wall->bottomRight().y, wall->topRight().x, wall->topRight().y}};
  33.            
  34.             vector<vector<float>> linesWithDistance;
  35.  
  36.             // calculate and sort based on shortest distance from the line to the point
  37.             for (int i = 0; i < lines.size(); ++i)
  38.             {
  39.                 float distance = position.distanceToLine({lines[i][0], lines[i][1]}, {lines[i][2], lines[i][3]});
  40.                 if (distance < unit->sightRange_)
  41.                 {
  42.                     linesWithDistance.push_back({distance, lines[i][0], lines[i][1], lines[i][2], lines[i][3]});
  43.                 }
  44.             }
  45.             std::sort(linesWithDistance.begin(), linesWithDistance.end(), [](auto a, auto b) {return a.at(0) < b.at(0);});
  46.             int amount = 0;
  47.  
  48.             // set amount of relevant lines in range for each wall
  49.             if (linesWithDistance.size() >= 1)
  50.             {
  51.                 // if the distance to two lines of 1 wall are the same that means the shortest distance is to the endpoint of those lines
  52.                 // or the point is inside the wall which should never happen.
  53.                 if (linesWithDistance.size() != 1 && linesWithDistance[0][0] == linesWithDistance[1][0])
  54.                 {
  55.                     amount = 2;
  56.                 }
  57.                 else
  58.                 {
  59.                     amount = 1;
  60.                 }
  61.             }
  62.  
  63.             // amount is the amount of line segments of the wall will block vision. kinda like backface culling?
  64.             for (int i = 0; i < amount; ++i)
  65.             {
  66.                 vector<f2> intersectionPoints = position.circleIntersectsLine(unit->sightRange_,
  67.                     {linesWithDistance[i][1], linesWithDistance[i][2]}, {linesWithDistance[i][3], linesWithDistance[i][4]});
  68.                 if (intersectionPoints.size() == 2)
  69.                 {
  70.                     linesFinal.push_back(intersectionPoints[0]);
  71.                     linesFinal.push_back(intersectionPoints[1]);
  72.                 }
  73.                 else if (intersectionPoints.size() == 1)
  74.                 {
  75.                     if (f2(linesWithDistance[i][1], linesWithDistance[i][2]).insideCircle(position, unit->sightRange_))
  76.                     {
  77.                         linesFinal.push_back(intersectionPoints[0]);
  78.                         linesFinal.push_back({linesWithDistance[i][1], linesWithDistance[i][2]});
  79.                     }
  80.                     else if (f2(linesWithDistance[i][3], linesWithDistance[i][4]).insideCircle(position, unit->sightRange_))
  81.                     {
  82.                         linesFinal.push_back(intersectionPoints[0]);
  83.                         linesFinal.push_back({linesWithDistance[i][3], linesWithDistance[i][4]});
  84.                     }
  85.                 }
  86.                 else
  87.                 {
  88.                     linesFinal.push_back({linesWithDistance[i][1], linesWithDistance[i][2]});
  89.                     linesFinal.push_back({linesWithDistance[i][3], linesWithDistance[i][4]});
  90.                 }
  91.             }
  92.         }
  93.     }
  94.  
  95.     // calculate starting and ending angles and sort based on starting angles and calculate the size of the angle
  96.     vector<vector<float>> anglesSet;
  97.     for (int i = 0; i + 1 < linesFinal.size(); i += 2)
  98.     {
  99.         float angle1 = atan2f((linesFinal[i].y - center.y), (linesFinal[i].x - center.x));
  100.         float angle2 = atan2f((linesFinal[i + 1].y - center.y), (linesFinal[i + 1].x - center.x));
  101.         // generate the linesegment angle data
  102.         // this splits angles that go a across the angle boundary from PI to -PI
  103.         if (angle1 - angle2 > PI)
  104.         {
  105.             f2 intersection = center.linesIntersect(center + f2( - unit->sightRange_, 0), linesFinal[i], linesFinal[i + 1]);
  106.             anglesSet.push_back({angle1, float(PI), linesFinal[i].x, linesFinal[i].y, intersection.x, intersection.y});
  107.             anglesSet.push_back({ float(- PI), angle2, intersection.x, intersection.y, linesFinal[i + 1].x, linesFinal[i + 1].y});
  108.         }
  109.         else if (angle1 - angle2 < - PI)
  110.         {
  111.             f2 intersection = center.linesIntersect(center + f2( - unit->sightRange_, 0), linesFinal[i], linesFinal[i + 1]);
  112.             anglesSet.push_back({angle2, float(PI), linesFinal[i + 1].x, linesFinal[i + 1].y, intersection.x, intersection.y});
  113.             anglesSet.push_back({ float(- PI), angle1, intersection.x, intersection.y, linesFinal[i].x, linesFinal[i].y});
  114.         }
  115.         else if (angle1 > angle2)
  116.         {
  117.             anglesSet.push_back({angle2, angle1, linesFinal[i + 1].x, linesFinal[i + 1].y, linesFinal[i].x, linesFinal[i].y});
  118.         }
  119.         else if (angle2 > angle1)
  120.         {
  121.             anglesSet.push_back({angle1, angle2, linesFinal[i].x, linesFinal[i].y, linesFinal[i + 1].x, linesFinal[i + 1].y});
  122.         }
  123.     }
  124.  
  125.     // split intersecting lines into seperate lines.
  126.     splitIntersectingLines(&anglesSet, center);
  127.  
  128.     // sort based on starting angle going clockwise.
  129.     std::sort(anglesSet.begin(), anglesSet.end(), [](auto a, auto b)
  130.         {
  131.             if (a.at(0) == b.at(0))
  132.             {
  133.                 return a.at(1) > b.at(1);
  134.             }
  135.             return a.at(0) < b.at(0);
  136.         });
  137.  
  138.     setFogTries(center, unit->sightRange_, anglesSet, vertices);
  139. }
Add Comment
Please, Sign In to add comment