示例#1
0
/* int Dstar::computeShortestPath()
 * --------------------------
 * As per [S. Koenig, 2002] except for 2 main modifications:
 * 1. We stop planning after a number of steps, 'maxsteps' we do this
 *    because this algorithm can plan forever if the start is
 *    surrounded by obstacles.
 * 2. We lazily remove states from the open list so we never have to
 *    iterate through it.
 */
int Dstar::computeShortestPath() {

  list<state> s;
  list<state>::iterator i;

  if (openList.empty()) return 1;

  int k=0;
  while ((!openList.empty()) &&
         (openList.top() < (s_start = calculateKey(s_start))) ||
         (getRHS(s_start) != getG(s_start))) {

    if (k++ > maxSteps) {
      fprintf(stderr, "At maxsteps\n");
      return -1;
    }


    state u;

    bool test = (getRHS(s_start) != getG(s_start));

    // lazy remove
    while(1) {
      if (openList.empty()) return 1;
      u = openList.top();
      openList.pop();

      if (!isValid(u)) continue;
      if (!(u < s_start) && (!test)) return 2;
      break;
    }

    ds_oh::iterator cur = openHash.find(u);
    openHash.erase(cur);

    state k_old = u;

    if (k_old < calculateKey(u)) { // u is out of date
      insert(u);
    } else if (getG(u) > getRHS(u)) { // needs update (got better)
      setG(u,getRHS(u));
      getPred(u,s);
      for (i=s.begin();i != s.end(); i++) {
        updateVertex(*i);
      }
    } else {   // g <= rhs, state has got worse
      setG(u,INFINITY);
      getPred(u,s);
      for (i=s.begin();i != s.end(); i++) {
        updateVertex(*i);
      }
      updateVertex(u);
    }
  }
  return 0;
}
示例#2
0
/* int Dstar::computeShortestPath()
 * --------------------------
 * As per [S. Koenig, 2002] except for 2 main modifications:
 * 1. We stop planning after a number of steps, 'maxsteps' we do this
 *    because this algorithm can plan forever if the start is
 *    surrounded by obstacles. 
 * 2. We lazily remove states from the open list so we never have to
 *    iterate through it.
 */
int Dstar::computeShortestPath() {
  
  list<state> s;
  list<state>::iterator i;

  if (openList.empty()) return 1;

  int k=0;
  while ((!openList.empty()) && 
         (openList.top() < (calculateKey(s_start))) || 
         (!isConsistent(s_start))) {

    if (k++ > maxSteps) {
      fprintf(stderr, "At maxsteps\n");
      return -1;
    }
    
    
    state u;
    
    // check consistency (one of the loop conditions)
    bool test = isConsistent(s_start);
    //(getRHS(s_start) != getG(s_start));
    
    // lazy remove
    while(1) { 
      if (openList.empty()) return 1; // checks outer loop condition #1
      u = openList.top();
      
      if (!queuePop()) continue;
      
      if (!(u < s_start) && test) return 2; // checks outer loop conditions #2,3 still hold
    
      break;
    }
    
    state k_old = u;

    if (k_old < calculateKey(u)) { // u is out of date
      insert(u); // u has been removed already, reinsert into pq with new key
    } else if (getG(u) > getRHS(u)) { // needs update (got better)
      setG(u,getRHS(u));
      getPred(u,s);
      for (i=s.begin();i != s.end(); i++) {
        updateVertex(*i);
      }
    } else {   // g <= rhs, state has got worse
      setG(u,INFINITY);
      getPred(u,s);
      for (i=s.begin();i != s.end(); i++) {
        updateVertex(*i);
      }
      updateVertex(u);
    }
  }
  return 0;
}
示例#3
0
static bool
exportFaceGroupToShape(
  shape_t& shape,
  std::map<vertex_index, unsigned int> vertexCache,
  const std::vector<float> &in_positions,
  const std::vector<float> &in_normals,
  const std::vector<float> &in_texcoords,
  const std::vector<std::vector<vertex_index> >& faceGroup,
  const int material_id,
  const std::string &name,
  bool clearCache)
{
  if (faceGroup.empty()) {
    return false;
  }

  size_t offset;

  offset = shape.mesh.indices.size();

  // Flatten vertices and indices
  for (size_t i = 0; i < faceGroup.size(); i++) {
    const std::vector<vertex_index>& face = faceGroup[i];

    vertex_index i0 = face[0];
    vertex_index i1(-1);
    vertex_index i2 = face[1];

    size_t npolys = face.size();

    // Polygon -> triangle fan conversion
    for (size_t k = 2; k < npolys; k++) {
      i1 = i2;
      i2 = face[k];

      unsigned int v0 = updateVertex(vertexCache, shape.mesh.positions, shape.mesh.normals, shape.mesh.texcoords, in_positions, in_normals, in_texcoords, i0);
      unsigned int v1 = updateVertex(vertexCache, shape.mesh.positions, shape.mesh.normals, shape.mesh.texcoords, in_positions, in_normals, in_texcoords, i1);
      unsigned int v2 = updateVertex(vertexCache, shape.mesh.positions, shape.mesh.normals, shape.mesh.texcoords, in_positions, in_normals, in_texcoords, i2);

      shape.mesh.indices.push_back(v0);
      shape.mesh.indices.push_back(v1);
      shape.mesh.indices.push_back(v2);

      shape.mesh.material_ids.push_back(material_id);
    }

  }

  shape.name = name;

  if (clearCache)
      vertexCache.clear();

  return true;

}
示例#4
0
static bool exportFaceGroupToShape( std::map<vertex_index, ssize_t>& vertexCache, ObjLoader::shapes_t& shapes, const std::vector<float> &in_positions,
                       const std::vector<float> &in_normals, const std::vector<float> &in_texcoords, const std::vector<std::vector<vertex_index> >& faceGroup,
                       const ObjLoader::material_t &material, const std::string &name)
{
    if (faceGroup.empty()) 
    {
        return false;
    }
    
    // Flattened version of vertex data
    std::vector<float>& positions = shapes.positions;
    std::vector<float>& normals = shapes.normals;
    std::vector<float>& texcoords = shapes.texcoords;
    std::vector<unsigned short> indices;
    
    // Flatten vertices and indices
    for (size_t i = 0; i < faceGroup.size(); i++) 
    {
        const std::vector<vertex_index>& face = faceGroup[i];
        
        vertex_index i0 = face[0];
        vertex_index i1(-1);
        vertex_index i2 = face[1];
        
        size_t npolys = face.size();
        
        // Polygon -> triangle fan conversion
        for (size_t k = 2; k < npolys; k++) 
        {
            i1 = i2;
            i2 = face[k];
            
            unsigned short v0 = updateVertex(vertexCache, positions, normals, texcoords, in_positions, in_normals, in_texcoords, i0);
            unsigned short v1 = updateVertex(vertexCache, positions, normals, texcoords, in_positions, in_normals, in_texcoords, i1);
            unsigned short v2 = updateVertex(vertexCache, positions, normals, texcoords, in_positions, in_normals, in_texcoords, i2);
            
            indices.push_back(v0);
            indices.push_back(v1);
            indices.push_back(v2);
        }
    }
    
    ObjLoader::shape_t shape;
    shape.name = name;
    shape.material = material;
    shape.mesh.indices.swap(indices);
    
    shapes.shapes.push_back(shape);
    return true;
    
}
示例#5
0
void Field::updateAllVertex(bool endgame, bool force) {
	bool was_debugging = is_debugging;
	is_debugging = false;
	unsigned int no_updates = 0;
	for (uint i = 0; i < field.size(); ++i) {
		if (field[i].update_vertex || force) {
			updateVertex(i,endgame);
			field[i].update_vertex = false;
			no_updates++;
		}
	}
	is_debugging = was_debugging;
	if (is_debugging && no_updates > 0) {
		if (no_updates == field.size())
			cout << "All";
		else
			cout << no_updates;
		cout << " vertex(es) updated (";
		if (force)
			cout << "forced";
		else
			cout << "not forced";
		cout << ")\n";
	}
}
示例#6
0
//--------------------------------------------------------------
void ofxFatLine::updateMesh(){
    meshVertices.clear();
    meshColors.clear();
    meshIndices.clear();
    for (int i =0; i<getVertices().size(); i++) {
        updateVertex(i);
        /*
         ofVec3f a (getVertices()[i-1] - getVertices()[i]);
         ofVec3f b (getVertices()[i+1] - getVertices()[i]);
         
         float  angle = a.angle(b);
         
         ofVec3f p = getMidVector(a, b);
         bool flip = !sameSideOfLine(p, flippepMidVectors.back(), getVertices()[i-1], getVertices()[i]);
         
         float cs = cos(DEG_TO_RAD * (90 - angle*0.5f));
         pushNewVertex(getVertices()[i], p, i, cs, flip);
         //*/
        
    }   
    
    mesh.clear();
    mesh.addVertices(meshVertices);
    mesh.addColors(meshColors);
    mesh.addIndices(meshIndices);
    // updateMeshIndices();
}
示例#7
0
/* void Dstar::updateCell(int x, int y, double val)
 * --------------------------
 * As per [S. Koenig, 2002]
 */
void Dstar::updateCell(int x, int y, double val) {

   state u;

  u.x = x;
  u.y = y;

  if ((u == s_start) || (u == s_goal)) return;

  makeNewCell(u);
  cellHash[u].cost = val;

  updateVertex(u);
}
示例#8
0
/* void Dstar::updateCell(int x, int y, double val)
 * --------------------------
 * As per [S. Koenig, 2002]
 */
void Dstar::updateCell(int x, int y, double val) {
  
  state u;
  
  u.x = x;
  u.y = y;

  if ((u == s_start) || (u == s_goal)) return;

  // if the value is still the same, don't need to do anything
  ds_ch::iterator cur = cellHash.find(u);
  if ((cur != cellHash.end()) && (near(cur->second.cost,val))) return;
  
  makeNewCell(u);
  cellHash[u].cost = val;
  
  updateVertex(u);
}
示例#9
0
void Sprite::scale(float factorX, float factorY)
{
	Transformable::scale(factorX, factorY);

	updateVertex();
}
示例#10
0
void TriangleMesh::updateAllVertices() {
  VertexIterator vitr = vertexBegin();
  VertexIterator end = vertexEnd();
  for(; vitr != end; ++vitr)
    updateVertex(**vitr);
}
示例#11
0
static bool
exportFaceGroupToShape(
  shape_t& shape,
  const std::vector<float> &in_positions,
  const std::vector<float> &in_normals,
  const std::vector<float> &in_texcoords,
  const std::vector<std::vector<vertex_index> >& faceGroup,
  const material_t &material,
  const std::string &name,
  const bool is_material_seted)
{
  if (faceGroup.empty()) {
    return false;
  }

  // Flattened version of vertex data
  std::vector<float> positions;
  std::vector<float> normals;
  std::vector<float> texcoords;
  std::map<vertex_index, unsigned int> vertexCache;
  std::vector<unsigned int> indices;

  // Flatten vertices and indices
  for (size_t i = 0; i < faceGroup.size(); i++) {
    const std::vector<vertex_index>& face = faceGroup[i];

    vertex_index i0 = face[0];
    vertex_index i1(-1);
    vertex_index i2 = face[1];

    size_t npolys = face.size();

    // Polygon -> triangle fan conversion
    for (size_t k = 2; k < npolys; k++) {
      i1 = i2;
      i2 = face[k];

      unsigned int v0 = updateVertex(vertexCache, positions, normals, texcoords, in_positions, in_normals, in_texcoords, i0);
      unsigned int v1 = updateVertex(vertexCache, positions, normals, texcoords, in_positions, in_normals, in_texcoords, i1);
      unsigned int v2 = updateVertex(vertexCache, positions, normals, texcoords, in_positions, in_normals, in_texcoords, i2);

      indices.push_back(v0);
      indices.push_back(v1);
      indices.push_back(v2);
    }

  }

  //
  // Construct shape.
  //
  shape.name = name;
  shape.mesh.positions.swap(positions);
  shape.mesh.normals.swap(normals);
  shape.mesh.texcoords.swap(texcoords);
  shape.mesh.indices.swap(indices);

  if(is_material_seted) {
    shape.material = material;
  } else {
    InitMaterial(shape.material);
    shape.material.diffuse[0] = 1.f;
    shape.material.diffuse[1] = 1.f;
    shape.material.diffuse[2] = 1.f;
  }

  return true;

}
示例#12
0
void Sprite::setPosition(float x, float y)
{
	Transformable::setPosition(x, y);

	updateVertex();
}
示例#13
0
void Field::updateVertex(unsigned int x,unsigned int y, bool endgame) {
	updateVertex(y*size.y+x, endgame);
}
示例#14
0
void Sprite::setPosition(const sf::Vector2f &position)
{
	Transformable::setPosition(position);

	updateVertex();
}
示例#15
0
/*
This method does the same thing as the pseudo-code's updateVertex(),
except for grids instead of graphs.

Pathfinding algorimths tend to be demonstraited with a graph rather than a grid,
in order to update the cost between two tiles we must update both the tile and its neighbour.
*/
void GridWorld::updateCost(unsigned int x, unsigned int y, double newCost){
	static int count = 1;
	count++;
	Tile* tile = getTileAt(x, y);
	
	printf("Updating <%d, %d> from %2.0lf to %2.0lf - Update: %d\n", x, y, tile->cost, newCost, count);
	km += calculateH(previous);
	previous = goal;

	//I am aware that the following code below could be refactored by 50%
	//since it's repeating itself with only a few changes

	double oldCost = tile->cost;
	double oldCostToTile, newCostToTile;

	//Update CURRENT by finding its new minimum RHS-value from NEIGHBOURS
	std::vector<Tile*> neighbours(getNeighbours(tile));
	for (int i = 0; i < neighbours.size(); i++){
		tile->cost = oldCost;
		oldCostToTile = calculateC(tile, neighbours[i]);

		tile->cost = newCost;
		newCostToTile = calculateC(tile, neighbours[i]);

		if (oldCostToTile > newCostToTile){
			if (tile != start && tile->rhs > neighbours[i]->g + newCostToTile){
				tile->successor = neighbours[i];
				tile->rhs = neighbours[i]->g + newCostToTile;
			}
		}
		else if (tile != start && tile->successor == neighbours[i]){
			TilePair minSucc(getMinSuccessor(tile));
			tile->rhs = minSucc.second;
			tile->successor = (tile->rhs == PF_INFINITY ? 0 : minSucc.first);
		}
	}

	updateVertex(tile);

	//Update all NEIGHBOURING cells by finding their new min RHS-values from CURRENT
	for (int i = 0; i < neighbours.size(); i++){
		tile->cost = oldCost;
		oldCostToTile = calculateC(tile, neighbours[i]);

		tile->cost = newCost;
		newCostToTile = calculateC(tile, neighbours[i]);

		if (oldCostToTile > newCostToTile){
			if (neighbours[i] != start && neighbours[i]->rhs > tile->g + newCostToTile){
				neighbours[i]->successor = tile;
				neighbours[i]->rhs = tile->g + newCostToTile;
				updateVertex(neighbours[i]);
			}

		}
		else if (neighbours[i] != start && neighbours[i]->successor == tile){
			TilePair minSucc(getMinSuccessor(neighbours[i]));
			neighbours[i]->rhs = minSucc.second;
			neighbours[i]->successor = (neighbours[i]->rhs == PF_INFINITY ? 0 : minSucc.first);

			updateVertex(neighbours[i]);
		}
	}

	computeShortestPath();
}
示例#16
0
vector<Grid> Planner::dStarLite(Map &map)
{
    // this is the implementation of the D star lite algorithm
    
    vector<Grid> wayPoint;

    
    // Initialization
    vector<vector<int> > g(map._rows,vector<int>(map._cols,map._rows*map._cols+1));
    vector<vector<int> > rhs(map._rows,vector<int>(map._cols,map._rows*map._cols+1));
    km =0;
    rhs[map.goal.y][map.goal.x] =0;
    Key n = calculateKey(map.goal,g,rhs,map.start,0);
    U.push_back({map.goal,n});
    
    
    // Computer current shortest path
    // Update the states of the map if the first element in the priority list can be updated or the goal is not reached
    while(U.front().key<calculateKey(map.goal,g,rhs,map.start,0)||(rhs[map.start.y][map.start.x]!=g[map.start.y][map.start.x]))
          {
              // take the key value and postion of the first element in the priority queue
              Key kold = U.front().key;
              Grid u = U.front().point;
              
              U.pop_front();
              Key knew = calculateKey(u,g,rhs,map.start,km); // calculate the new key value
              
              // update map if old value is different from the new value
              if (kold<knew)
              {
                  // if the new key is larger, the cost of the edge of the grid might be change
                  // the current grid should be updated and re-expanded
                  // insert it in the priority queue
                  auto pt =find_if(U.begin(),U.end(),[knew](Uelem &u){return u.key<knew;});
                  U.insert(pt,{u,knew});
              }
              else if (g[u.y][u.x]>rhs[u.y][u.x])
              {
                  // if the grid is overconstraint, there are new shorter paths detected
                  g[u.y][u.x] = rhs[u.y][u.x];
                  
                  // update all its neighbour value
                  vector<Grid> neightbour = findNeighbour(map, u, 8);
                  for(auto &n:neightbour)
                  {
                      updateVertex(U,n,g,rhs,map,km);
                  }
              }
              else
              {
                  // if the grid is underconstraint, the grid it self and its neightbour should all be updated
                  g[u.y][u.x] = map._cols*map._rows;
                  vector<Grid> neightbour = findNeighbour(map, u, 8);
                  for(auto &n:neightbour)
                  {
                      updateVertex(U,n,g,rhs,map,km);
                  }
                  updateVertex(U,u,g,rhs,map,km);
              }
              
                  
              
              
              
          }
    
    return wayPoint;
}
示例#17
0
/*
This method does the same thing as the pseudo-code's updateVertex(),
except for grids instead of graphs.

Pathfinding algorimths tend to be demonstraited with a graph rather than a grid,
in order to update the cost between two tiles we must update both the tile and its neighbour.
*/
void GridWorld::updateCost(unsigned int x, unsigned int y, double newCost){
	static int count = 1;
	count++;
	Tile* tile = getTileAt(x, y);

	printf("Updating <%d, %d> from %2.0lf to %2.0lf - Update: %d\n", x, y, tile->cost, newCost, count);
	km += calculateH(previous);
	previous = start;

	//I am aware that the following code below could be refactored by 50%
	//since it's repeating itself with only a few changes

	double oldCost = tile->cost;
	double oldCostToTile, newCostToTile;
	double currentRHS, otherG;

	//Update CURRENT by finding its new minimum RHS-value from NEIGHBOURS
	std::vector<Tile*> neighbours(getNeighbours(tile));
	for (int i = 0; i < neighbours.size(); i++){
		tile->cost = oldCost;
		oldCostToTile = calculateC(tile, neighbours[i]);

		tile->cost = newCost;
		newCostToTile = calculateC(tile, neighbours[i]);

		currentRHS = tile->rhs;
		otherG = neighbours[i]->g;

		if (oldCostToTile > newCostToTile){
			if (tile != goal){
				tile->rhs = std::min(currentRHS, (newCostToTile + otherG));
			}
		}
		else if (currentRHS == (oldCostToTile + otherG)){
			if (tile != goal){
				tile->rhs = getMinSuccessor(tile).second;
			}
		}
	}

	updateVertex(tile);

	//Update all NEIGHBOURING cells by finding their new min RHS-values from CURRENT
	for (int i = 0; i < neighbours.size(); i++){
		tile->cost = oldCost;
		oldCostToTile = calculateC(tile, neighbours[i]);

		tile->cost = newCost;
		newCostToTile = calculateC(tile, neighbours[i]);

		currentRHS = neighbours[i]->rhs;
		otherG = tile->g;

		if (oldCostToTile > newCostToTile){
			if (neighbours[i] != goal){
				neighbours[i]->rhs = std::min(currentRHS, (newCostToTile + otherG));
			}
		}
		else if (currentRHS == (oldCostToTile + otherG)){
			if (neighbours[i] != goal){
				neighbours[i]->rhs = getMinSuccessor(neighbours[i]).second;
			}
		}
		updateVertex(neighbours[i]);
	}

	computeShortestPath();
}
示例#18
0
bool GridWorld::computeShortestPath(){
	if (open.empty()){
		std::cout << "ERROR: No tiles to expand on... can't do anything" << std::endl;
		return false;
	}


	while (!open.empty() && (compareKeys(open.front()->key, goal->key = calculateKey(goal)) || goal->rhs != goal->g)){
		Tile* current = open.front();
		//Notice that CURRENT wasn't pop/removed yet

		//std::cout << "Expanding:";
		//current->info();
		//std::cout << std::endl;
		KeyPair k_new = calculateKey(current);

		if (compareKeys(current->key, k_new)){
			//Tiles under this branch will have to be updated as incremental search has happened
			current->key = k_new;
			make_heap(open.begin(), open.end(), GridWorld::compareTiles);

		}
		else if (current->g > current->rhs){
			//Majority of the tiles will fall under this conditional branch as
			//it undergoes normal A* pathfinding

			current->g = current->rhs;

			open.erase(open.begin());
			make_heap(open.begin(), open.end(), GridWorld::compareTiles);
			current->isOpen = false;

			std::vector<Tile*> neighbours(getNeighbours(current));
			for (int i = 0; i < neighbours.size(); i++){
				if (neighbours[i] != start && neighbours[i]->rhs > current->g + calculateC(current, neighbours[i])){
					neighbours[i]->successor = current;
					neighbours[i]->rhs = current->g + calculateC(current, neighbours[i]);
					updateVertex(neighbours[i]);
				}
			}

		}
		else {
			//Tiles under this branch will need to be updated during incremental search
			current->g = PF_INFINITY;

			//Update CURRENT
			if (current != start && current->successor == current){
				TilePair minSucc(getMinSuccessor(current));
				current->rhs = minSucc.second;
				current->successor = current->rhs == PF_INFINITY ? 0 : minSucc.first;
			}
			updateVertex(current);

			//Update NEIGHBOURS
			std::vector<Tile*> neighbours(getNeighbours(current));
			for (int i = 0; i < neighbours.size(); i++){
				if (neighbours[i] != start && neighbours[i]->successor == current){
					TilePair minSucc(getMinSuccessor(neighbours[i]));
					neighbours[i]->rhs = minSucc.second;
					neighbours[i]->successor = neighbours[i]->rhs == PF_INFINITY ? 0 : minSucc.first;
				}
				updateVertex(neighbours[i]);
			}

		}
		//Uncomment this to see CURRENT'S new values
		//std::cout << "Expanded:";
		//current->info();
		//std::cout << std::endl;
	}
	return true;
}
示例#19
0
void SceneE::update(){
    updateVertex();
}
示例#20
0
void Sprite::rotate(float angle)
{
	Transformable::rotate(angle);

	updateVertex();
}
示例#21
0
void Sprite::move(const sf::Vector2f &offset)
{
	Transformable::move(offset);

	updateVertex();
}
示例#22
0
void Sprite::move(float offsetX, float offsetY)
{
	Transformable::move(offsetX, offsetY);

	updateVertex();
}
示例#23
0
void Sprite::setRotation(float angle)
{
	Transformable::setRotation(angle);

	updateVertex();
}
示例#24
0
void Sprite::scale(const sf::Vector2f &factor)
{
	Transformable::scale(factor);

	updateVertex();
}
示例#25
0
bool GridWorld::computeShortestPath(){
	if (open.empty()){
		std::cout << "ERROR: No tiles to expand on... can't do anything" << std::endl;
		return false;
	}

	double currentRHS, otherG, previousG;

	while (!open.empty() && (compareKeys(open.front()->key, start->key = calculateKey(start)) || start->rhs != start->g)){
		Tile* current = open.front();
		//Notice that CURRENT wasn't pop/removed yet..

		KeyPair k_old = current->key;
		KeyPair k_new = calculateKey(current);

		currentRHS = current->rhs;
		otherG = current->g;

		/*std::cout << "Expanding:";
		current->info();
		std::cout << std::endl;*/

		if (compareKeys(k_old, k_new)){
			//This branch updates tile that were already in the OPEN list originally
			//This branch tends to execute AFTER the else branch
			current->key = k_new;
			make_heap(open.begin(), open.end(), GridWorld::compareTiles);

		}
		else if (otherG > currentRHS){
			//Majority of the execution will fall under this conditional branch as
			//it is undergoing normal A* pathfinding

			current->g = current->rhs;
			otherG = currentRHS;

			open.erase(open.begin());
			make_heap(open.begin(), open.end(), GridWorld::compareTiles);
			current->isOpen = false;

			std::vector<Tile*> neighbours(getNeighbours(current));
			for (int i = 0; i < neighbours.size(); i++){
				if (neighbours[i] != 0){
					if (neighbours[i] != goal){
						neighbours[i]->rhs = std::min(neighbours[i]->rhs, calculateC(current, neighbours[i]) + otherG);
					}
					updateVertex(neighbours[i]);
				}
			}

		}
		else {
			//Execution of this branch updates the tile during incremental search

			previousG = otherG;
			current->g = PF_INFINITY;

			//Update CURRENT'S RHS
			if (current != goal){
				current->rhs = getMinSuccessor(current).second;
			}
			updateVertex(current);

			//Update NEIGHBOUR'S RHS to their minimum successor
			std::vector<Tile*> neighbours(getNeighbours(current));
			for (int i = 0; i < neighbours.size(); i++){
				if (neighbours[i] != 0){
					if (neighbours[i]->rhs == (calculateC(current, neighbours[i]) + previousG) && neighbours[i] != goal){
						neighbours[i]->rhs = getMinSuccessor(neighbours[i]).second;
					}
					updateVertex(neighbours[i]);
				}
			}

		}
		//Uncomment this to see CURRENT'S new values
		//std::cout << "Expanded:";
		//current->info();
		//std::cout << std::endl;
	}
	return true;
}