@@ -787,8 +787,7 @@ void CGame::GraphReset()
787787{
788788 m_eGraphStep = GRAPHSTEP_PUSHTOSTACK;
789789 m_aiNodeStack.clear ();
790- m_iTestNode = ~0 ;
791- m_iTestEdge = ~0 ;
790+ m_aiPathStack.clear ();
792791
793792 m_Graph = CGraph ();
794793
@@ -822,66 +821,66 @@ void CGame::GraphStep()
822821 if (m_eGraphStep == GRAPHSTEP_PUSHTOSTACK)
823822 {
824823 m_aiNodeStack.push_back (0 );
825- m_eGraphStep = GRAPHSTEP_MARKSEEN;
824+ m_Graph.GetNode (m_aiNodeStack[0 ])->seen = true ;
825+ m_eGraphStep = GRAPHSTEP_PUSHNEIGHBORS;
826826 }
827- else if (m_eGraphStep == GRAPHSTEP_MARKSEEN )
827+ else if (m_eGraphStep == GRAPHSTEP_PUSHNEIGHBORS )
828828 {
829- m_Graph.GetNode (m_aiNodeStack.back ())-> seen = true ;
829+ CGraph::CNode* current_node = m_Graph.GetNode (m_aiNodeStack.front ());
830830
831- m_iTestEdge = 0 ;
831+ size_t i;
832+ for (i = 0 ; i < current_node->edges .size (); i++)
833+ {
834+ edge_t edge = current_node->edges [i];
832835
833- m_eGraphStep = GRAPHSTEP_FOLLOWEDGES;
834- }
835- else if (m_eGraphStep == GRAPHSTEP_FOLLOWEDGES)
836- {
837- CGraph::CNode* current_node = m_Graph.GetNode (m_aiNodeStack.back ());
836+ node_t test_node = m_Graph.FollowEdge (m_aiNodeStack.front (), edge);
838837
839- if ((size_t )m_iTestEdge >= current_node->edges .size ())
840- {
841- // We've run out of edges. There are no unseen nodes! We should go back.
842- m_eGraphStep = GRAPHSTEP_POPNODE;
843- return ;
844- }
838+ if (m_Graph.GetNode (test_node) == m_pTargetNode)
839+ {
840+ // We found it! Stash our data for the reconstruct step.
841+ m_pTargetNode->path_from = m_aiNodeStack.front ();
842+ m_aiNodeStack.push_back (test_node);
845843
846- edge_t edge = current_node->edges [m_iTestEdge];
844+ m_eGraphStep = GRAPHSTEP_RECONSTRUCT;
845+ return ;
846+ }
847847
848- m_iTestNode = m_Graph.FollowEdge (m_aiNodeStack.back (), edge);
848+ if (m_Graph.GetNode (test_node)->seen )
849+ continue ;
849850
850- // Next time we'll test the next edge.
851- m_iTestEdge++;
851+ // We haven't seen this node. Push it to the stack.
852+ m_aiNodeStack.push_back (test_node);
853+ m_Graph.GetNode (test_node)->path_from = m_aiNodeStack.front ();
854+ }
852855
853- m_eGraphStep = GRAPHSTEP_TESTS ;
856+ m_eGraphStep = GRAPHSTEP_MARKSEEN ;
854857 }
855- else if (m_eGraphStep == GRAPHSTEP_TESTS )
858+ else if (m_eGraphStep == GRAPHSTEP_MARKSEEN )
856859 {
857- if (m_Graph.GetNode (m_iTestNode) == m_pTargetNode)
858- {
859- // We're done!
860- m_aiNodeStack.push_back (m_iTestNode);
861- return ;
862- }
860+ // Technically we only need to mark the ones that were just added as seen but this is just sample code.
861+ // See below for the actual code where they're only added when seen.
862+ for (size_t i = 0 ; i < m_aiNodeStack.size (); i++)
863+ m_Graph.GetNode (m_aiNodeStack[i])->seen = true ;
863864
864- if (m_Graph.GetNode (m_iTestNode)->seen )
865- {
866- // We've already seen this node. Pick another.
867- m_eGraphStep = GRAPHSTEP_FOLLOWEDGES;
868- return ;
869- }
870-
871- m_eGraphStep = GRAPHSTEP_PUSHNODE;
865+ m_eGraphStep = GRAPHSTEP_POPFRONT;
872866 }
873- else if (m_eGraphStep == GRAPHSTEP_PUSHNODE )
867+ else if (m_eGraphStep == GRAPHSTEP_POPFRONT )
874868 {
875- m_aiNodeStack.push_back (m_iTestNode );
869+ m_aiNodeStack.pop_front ( );
876870
877- m_eGraphStep = GRAPHSTEP_MARKSEEN ;
871+ m_eGraphStep = GRAPHSTEP_PUSHNEIGHBORS ;
878872 }
879- else if (m_eGraphStep == GRAPHSTEP_POPNODE )
873+ else if (m_eGraphStep == GRAPHSTEP_RECONSTRUCT )
880874 {
881- // This is not the node we're looking for.
882- m_aiNodeStack.pop_back ();
875+ node_t current_node = m_aiNodeStack.back ();
883876
884- m_eGraphStep = GRAPHSTEP_MARKSEEN;
877+ m_aiPathStack.push_back (current_node);
878+
879+ while (m_Graph.GetNode (current_node)->path_from != ~0 )
880+ {
881+ current_node = m_Graph.GetNode (current_node)->path_from ;
882+ m_aiPathStack.push_back (current_node);
883+ }
885884 }
886885}
887886
@@ -890,40 +889,47 @@ void CGame::GraphComplete()
890889 GraphReset ();
891890
892891 m_aiNodeStack.push_back (0 );
892+ m_Graph.GetNode (m_aiNodeStack.back ())->seen = true ;
893893
894894 while (true )
895895 {
896- m_Graph.GetNode (m_aiNodeStack.back ())->seen = true ;
897-
898- CGraph::CNode* current_node = m_Graph.GetNode (m_aiNodeStack.back ());
896+ CGraph::CNode* current_node = m_Graph.GetNode (m_aiNodeStack.front ());
899897
900898 size_t i;
901899 for (i = 0 ; i < current_node->edges .size (); i++)
902900 {
903901 edge_t edge = current_node->edges [i];
904902
905- node_t test_node = m_Graph.FollowEdge (m_aiNodeStack.back (), edge);
903+ node_t test_node = m_Graph.FollowEdge (m_aiNodeStack.front (), edge);
906904 if (m_Graph.GetNode (test_node) == m_pTargetNode)
907905 {
908906 // We're done!
909- m_aiNodeStack.push_back (test_node);
907+ m_pTargetNode->path_from = m_aiNodeStack.front ();
908+
909+ node_t current_node = test_node;
910+
911+ m_aiPathStack.push_back (current_node);
912+
913+ // Now we reconstruct the path.
914+ while (m_Graph.GetNode (current_node)->path_from != ~0 )
915+ {
916+ current_node = m_Graph.GetNode (current_node)->path_from ;
917+ m_aiPathStack.push_back (current_node);
918+ }
919+
910920 return ;
911921 }
912922
913923 if (m_Graph.GetNode (test_node)->seen )
914- // We've already seen this node. Pick another.
915924 continue ;
916925
917926 // We haven't seen this node. Push it to the stack.
918927 m_aiNodeStack.push_back (test_node);
919-
920- // Break out of this edges loop to go back to the beginning of the algorithm.
921- break ;
928+ m_Graph.GetNode (test_node)->seen = true ;
929+ m_Graph.GetNode (test_node)->path_from = m_aiNodeStack.front ();
922930 }
923931
924- if (i == current_node->edges .size ())
925- // We explored every edge and they were all unseen. This must be a dead end.
926- m_aiNodeStack.pop_back ();
932+ m_aiNodeStack.pop_front ();
927933 }
928934}
929935
@@ -936,10 +942,8 @@ void CGame::GraphDraw()
936942 CGraph::CNode* node = m_Graph.GetNode (i);
937943
938944 {
939- if (m_aiNodeStack.size () && m_aiNodeStack.back () == i)
945+ if (m_aiNodeStack.size () && m_aiNodeStack.front () == i)
940946 c.SetUniform (" vecColor" , Color (0 , 255 , 0 , 255 ));
941- else if (i == m_iTestNode)
942- c.SetUniform (" vecColor" , Color (255 , 255 , 0 , 255 ));
943947 else if (node == m_pTargetNode)
944948 c.SetUniform (" vecColor" , Color (255 , 120 , 0 , 255 ));
945949 else
@@ -975,15 +979,15 @@ void CGame::GraphDraw()
975979 CGraph::CNode* node2 = m_Graph.GetNode (edge->second );
976980
977981 bool in_path = false ;
978- for (int j = 0 ; j < ((int )m_aiNodeStack .size ())-1 ; j++)
982+ for (int j = 0 ; j < ((int )m_aiPathStack .size ())-1 ; j++)
979983 {
980- if (m_aiNodeStack [j] == edge->first && m_aiNodeStack [j+1 ] == edge->second )
984+ if (m_aiPathStack [j] == edge->first && m_aiPathStack [j+1 ] == edge->second )
981985 {
982986 in_path = true ;
983987 break ;
984988 }
985989
986- if (m_aiNodeStack [j] == edge->second && m_aiNodeStack [j+1 ] == edge->first )
990+ if (m_aiPathStack [j] == edge->second && m_aiPathStack [j+1 ] == edge->first )
987991 {
988992 in_path = true ;
989993 break ;
@@ -999,5 +1003,28 @@ void CGame::GraphDraw()
9991003 c.Vertex (node1->debug_position + Vector (0 , 0 .1f , 0 ));
10001004 c.Vertex (node2->debug_position + Vector (0 , 0 .1f , 0 ));
10011005 c.EndRender ();
1006+
1007+ Vector path_start, path_end;
1008+ bool show_path = false ;
1009+
1010+ if (node1->path_from == edge->second )
1011+ {
1012+ path_start = node1->debug_position ;
1013+ path_end = node2->debug_position ;
1014+ show_path = true ;
1015+ }
1016+ else if (node2->path_from == edge->first )
1017+ {
1018+ path_start = node2->debug_position ;
1019+ path_end = node1->debug_position ;
1020+ show_path = true ;
1021+ }
1022+
1023+ if (show_path)
1024+ {
1025+ float lerp = fmod (GetTime (), 1 );
1026+ Vector position = path_start * (1 -lerp) + path_end * lerp;
1027+ c.RenderBox (position - Vector (0 .2f , 0 .2f , 0 .2f ), position + Vector (0 .2f , 0 .2f , 0 .2f ));
1028+ }
10021029 }
10031030}
0 commit comments