Skip to content
/ Flow Public

An STL only, "bring-your-own AI agent" flow field navigation library

License

Notifications You must be signed in to change notification settings

stnKrisna/Flow

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Flow cover image

Documentation

Features

Planned features

  • Serialization
  • Deserialization
  • User embeded cell data
  • Cell exit restriction - Cell direction can only point to a certain direction.
  • Dynamic/real-time reaction - Flow direction is able to adapt to a dynamic environment without having to recalculate every single cell.

Example

Here is an example usage of this library.

Building flow field from ASCII map

flow::Field field(10, 8);

char map[] = "\
wwwwwwwwww\
w........w\
www.ww.www\
www.ww.www\
www.ww.www\
www.ww.www\
w........w\
w........w";

for (auto cell = field.begin(); cell != field.end(); ++cell) {
  cell->setAllowDiagonal(true);
  switch (map[cell.idx]) {
    case '.':
      cell->setEntryDir(flow::Directions::NORTH |
              flow::Directions::EAST |
              flow::Directions::SOUTH |
              flow::Directions::WEST);
      break;
    case 'w':
      cell->setEntryDir(0);
      cell->setAllowDiagonal(false);
      break;
  }
}

One-way traffic

char map[] = "\
wwwwwwwwww\
w........w\
www4ww1www\
www4ww1www\
www4ww1www\
www4ww1www\
w........w\
w........w";

for (auto cell = field.begin(); cell != field.end(); ++cell) {
  cell->setAllowDiagonal(true);
  switch (map[cell.idx]) {
    case '.':
      cell->setEntryDir(flow::Directions::NORTH |
              flow::Directions::EAST |
              flow::Directions::SOUTH |
              flow::Directions::WEST);
      break;
    case '1':
      cell->setEntryDir(flow::Directions::NORTH);
      break;
    case '4':
      cell->setEntryDir(flow::Directions::SOUTH);
      break;
    case 'w':
      cell->setEntryDir(0);
      cell->setAllowDiagonal(false);
      break;
  }
}

// Or use the "at" function to get a specific cell
field.at(1, 0).setEntryDir(flow::Directions::NORTH |
        flow::Directions::EAST |
        flow::Directions::SOUTH |
        flow::Directions::WEST);

STL-like cell iteration

// Begin-end loop
for (auto itr = field.begin(); itr != field.end(); ++itr) {
  // Print the index of the iterator
  std::cout << itr.idx << std::endl;

  // You can use the arrow operator (->) to access the cell
  itr->setEntryDir(flow::Directions::NORTH |
    flow::Directions::EAST |
    flow::Directions::SOUTH |
    flow::Directions::WEST);
}

// Range based loop
for (auto& cell : field) {
  // Convert every cell to a wall
  cell.setEntryDir(0);
}

for (auto cell : field) {
  // Everything is now a wall
  std::cout << cell.isWall() << " ";
}

Grid-based navigation

// BYO vector object
if (enemy.position == enemy.desiredPos) {
  uint16_t newPos_x = 0;
  uint16_t newPos_y = 0;

  field.getNextCell(0, (int)enemy.pos.x, (int)enemy.pos.y, &newPos_x, &newPos_y);

  enemy.desiredPos.x = newPos_x;
  enemy.desiredPos.y = newPos_y;
}

Vector-based navigation

// BYO vector object
Vector2 enemyDir;

// Get the normalized vector of the direction
field.getDirection(0, (int)enemy.pos.x, (int)enemy.pos.y, &enemyDir.x, &enemyDir.y);

// BYO vector math
enemy.pos += enemy.speed * enemyDir;

Inspiration

This project is inspired from this paper:

  • S. Patil, J. Van Den Berg, S. Curtis, M. C. Lin, en D. Manocha, “Directing crowd simulations using navigation fields”, IEEE transactions on visualization and computer graphics, vol 17, no 2, bll 244–254, 2010.

Releases

No releases published

Packages

No packages published