-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
301 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ add_sources(libopenage | |
integration_field.cpp | ||
integrator.cpp | ||
path.cpp | ||
portal.cpp | ||
tests.cpp | ||
types.cpp | ||
) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
// Copyright 2024-2024 the openage authors. See copying.md for legal info. | ||
|
||
#include "portal.h" | ||
|
||
#include "error/error.h" | ||
|
||
|
||
namespace openage::path { | ||
|
||
Portal::Portal(std::shared_ptr<CostField> sector0, | ||
std::shared_ptr<CostField> sector1, | ||
std::vector<std::shared_ptr<Portal>> sector0_exits, | ||
std::vector<std::shared_ptr<Portal>> sector1_exits, | ||
PortalDirection direction, | ||
size_t cell_start_x, | ||
size_t cell_start_y, | ||
size_t cell_end_x, | ||
size_t cell_end_y) : | ||
sector0{sector0}, | ||
sector1{sector1}, | ||
sector0_exits{sector0_exits}, | ||
sector1_exits{sector1_exits}, | ||
direction{direction}, | ||
cell_start_x{cell_start_x}, | ||
cell_start_y{cell_start_y}, | ||
cell_end_x{cell_end_x}, | ||
cell_end_y{cell_end_y} { | ||
} | ||
|
||
const std::vector<std::shared_ptr<Portal>> &Portal::get_exits(const std::shared_ptr<CostField> &entry_sector) const { | ||
ENSURE(entry_sector == this->sector0 || entry_sector == this->sector1, "Invalid entry sector"); | ||
|
||
if (entry_sector == this->sector0) { | ||
return this->sector1_exits; | ||
} | ||
return this->sector0_exits; | ||
} | ||
|
||
const std::shared_ptr<CostField> &Portal::get_exit_sector(const std::shared_ptr<CostField> &entry_sector) const { | ||
ENSURE(entry_sector == this->sector0 || entry_sector == this->sector1, "Invalid entry sector"); | ||
|
||
if (entry_sector == this->sector0) { | ||
return this->sector1; | ||
} | ||
return this->sector0; | ||
} | ||
|
||
std::pair<size_t, size_t> Portal::get_entry_start(const std::shared_ptr<CostField> &entry_sector) const { | ||
ENSURE(entry_sector == this->sector0 || entry_sector == this->sector1, "Invalid entry sector"); | ||
|
||
if (entry_sector == this->sector0) { | ||
return this->get_sector0_start(); | ||
} | ||
|
||
return this->get_sector1_start(); | ||
} | ||
|
||
std::pair<size_t, size_t> Portal::get_entry_end(const std::shared_ptr<CostField> &entry_sector) const { | ||
ENSURE(entry_sector == this->sector0 || entry_sector == this->sector1, "Invalid entry sector"); | ||
|
||
if (entry_sector == this->sector0) { | ||
return this->get_sector0_end(); | ||
} | ||
|
||
return this->get_sector1_end(); | ||
} | ||
|
||
std::pair<size_t, size_t> Portal::get_exit_start(const std::shared_ptr<CostField> &entry_sector) const { | ||
ENSURE(entry_sector == this->sector0 || entry_sector == this->sector1, "Invalid entry sector"); | ||
|
||
if (entry_sector == this->sector0) { | ||
return this->get_sector1_start(); | ||
} | ||
|
||
return this->get_sector0_start(); | ||
} | ||
|
||
std::pair<size_t, size_t> Portal::get_exit_end(const std::shared_ptr<CostField> &entry_sector) const { | ||
ENSURE(entry_sector == this->sector0 || entry_sector == this->sector1, "Invalid entry sector"); | ||
|
||
if (entry_sector == this->sector0) { | ||
return this->get_sector1_end(); | ||
} | ||
|
||
return this->get_sector0_end(); | ||
} | ||
|
||
std::pair<size_t, size_t> Portal::get_sector0_start() const { | ||
return {this->cell_start_x, this->cell_start_y}; | ||
} | ||
|
||
std::pair<size_t, size_t> Portal::get_sector0_end() const { | ||
return {this->cell_end_x, this->cell_end_y}; | ||
} | ||
|
||
std::pair<size_t, size_t> Portal::get_sector1_start() const { | ||
return {this->cell_end_x, this->cell_end_y}; | ||
} | ||
|
||
std::pair<size_t, size_t> Portal::get_sector1_end() const { | ||
return {this->cell_start_x, this->cell_start_y}; | ||
} | ||
|
||
} // namespace openage::path |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,196 @@ | ||
// Copyright 2024-2024 the openage authors. See copying.md for legal info. | ||
|
||
#pragma once | ||
|
||
|
||
#include <memory> | ||
|
||
#include "pathfinding/cost_field.h" | ||
|
||
|
||
namespace openage::path { | ||
class CostField; | ||
|
||
/** | ||
* Possible directions of a portal node. | ||
*/ | ||
enum class PortalDirection { | ||
NORTH_SOUTH, | ||
EAST_WEST | ||
}; | ||
|
||
/** | ||
* Biderectional gateway for connecting two sectors in the flow field pathfinder. | ||
* | ||
* Portals are located at the border of two sectors (0 and 1), and allow units to move between them. | ||
* For each of these sectors, the portal stores the start and end coordinates where the | ||
* sectors overlap as well as the other portals that can be reached in the same | ||
* sector. For simplicity, the portal is assumed to be a straight line of cells from the start | ||
* to the end. | ||
* | ||
* The portal is bidirectional, meaning that it can be entered from either sector and | ||
* exited into the other sector. The direction of the portal from one sector to the other | ||
* is stored in the portal node. As a convention and to simplify computations, sector 0 must be | ||
* the either the north or east sector on the grid in relation to sector 1. | ||
*/ | ||
class Portal { | ||
public: | ||
/** | ||
* Create a new portal between two sectors. | ||
* | ||
* As a convention, sector 0 must be the either the north or east sector | ||
* on the grid in relation to sector 1. | ||
* | ||
* @param sector0 First sector connected by the portal. | ||
* Must be north or east on the grid in relation to sector 1. | ||
* @param sector1 Second sector connected by the portal. | ||
* Must be south or west on the grid in relation to sector 0. | ||
* @param sector0_exits Portals reachable from this portal in sector 0. | ||
* @param sector1_exits Portals reachable from this portal in sector 1. | ||
* @param direction Direction of the portal from sector 0 to sector 1. | ||
* @param cell_start_x Start cell x coordinate in sector 0. | ||
* @param cell_start_y Start cell y coordinate in sector 0. | ||
* @param cell_end_x End cell x coordinate in sector 0. | ||
* @param cell_end_y End cell y coordinate in sector 0. | ||
*/ | ||
Portal(std::shared_ptr<CostField> sector0, | ||
std::shared_ptr<CostField> sector1, | ||
std::vector<std::shared_ptr<Portal>> sector0_exits, | ||
std::vector<std::shared_ptr<Portal>> sector1_exits, | ||
PortalDirection direction, | ||
size_t cell_start_x, | ||
size_t cell_start_y, | ||
size_t cell_end_x, | ||
size_t cell_end_y); | ||
|
||
~Portal() = default; | ||
|
||
/** | ||
* Get the exit portals reachable via the portal when entering from a specified sector. | ||
* | ||
* @param entry_sector Sector from which the portal is entered. | ||
* | ||
* @return Exit portals reachable from the portal. | ||
*/ | ||
const std::vector<std::shared_ptr<Portal>> &get_exits(const std::shared_ptr<CostField> &entry_sector) const; | ||
|
||
/** | ||
* Get the cost field of the sector where the portal is exited. | ||
* | ||
* @param entry_sector Sector from which the portal is entered. | ||
* | ||
* @return Cost field of the sector where the portal is exited. | ||
*/ | ||
const std::shared_ptr<CostField> &get_exit_sector(const std::shared_ptr<CostField> &entry_sector) const; | ||
|
||
/** | ||
* Get the cost field of the sector from which the portal is entered. | ||
* | ||
* @param entry_sector Sector from which the portal is entered. | ||
* | ||
* @return Cost field of the sector from which the portal is entered. | ||
*/ | ||
std::pair<size_t, size_t> get_entry_start(const std::shared_ptr<CostField> &entry_sector) const; | ||
|
||
/** | ||
* Get the cell coordinates of the start of the portal in the entry sector. | ||
* | ||
* @param entry_sector Sector from which the portal is entered. | ||
* | ||
* @return Cell coordinates of the start of the portal in the entry sector. | ||
*/ | ||
std::pair<size_t, size_t> get_entry_end(const std::shared_ptr<CostField> &entry_sector) const; | ||
|
||
/** | ||
* Get the cell coordinates of the start of the portal in the exit sector. | ||
* | ||
* @param entry_sector Sector from which the portal is entered. | ||
* | ||
* @return Cell coordinates of the start of the portal in the exit sector. | ||
*/ | ||
std::pair<size_t, size_t> get_exit_start(const std::shared_ptr<CostField> &entry_sector) const; | ||
|
||
/** | ||
* Get the cell coordinates of the end of the portal in the exit sector. | ||
* | ||
* @param entry_sector Sector from which the portal is entered. | ||
* | ||
* @return Cell coordinates of the end of the portal in the exit sector. | ||
*/ | ||
std::pair<size_t, size_t> get_exit_end(const std::shared_ptr<CostField> &entry_sector) const; | ||
|
||
private: | ||
/** | ||
* Get the start cell coordinates of the portal. | ||
* | ||
* @return Start cell coordinates of the portal. | ||
*/ | ||
std::pair<size_t, size_t> get_sector0_start() const; | ||
|
||
/** | ||
* Get the end cell coordinates of the portal. | ||
* | ||
* @return End cell coordinates of the portal. | ||
*/ | ||
std::pair<size_t, size_t> get_sector0_end() const; | ||
|
||
/** | ||
* Get the start cell coordinates of the portal. | ||
* | ||
* @return Start cell coordinates of the portal. | ||
*/ | ||
std::pair<size_t, size_t> get_sector1_start() const; | ||
|
||
/** | ||
* Get the end cell coordinates of the portal. | ||
* | ||
* @return End cell coordinates of the portal. | ||
*/ | ||
std::pair<size_t, size_t> get_sector1_end() const; | ||
|
||
/** | ||
* Sector 0 | ||
*/ | ||
std::shared_ptr<CostField> sector0; | ||
|
||
/** | ||
* Sector 1 | ||
*/ | ||
std::shared_ptr<CostField> sector1; | ||
|
||
/** | ||
* Exits from sector 0 | ||
*/ | ||
std::vector<std::shared_ptr<Portal>> sector0_exits; | ||
|
||
/** | ||
* Exits from sector 1 | ||
*/ | ||
std::vector<std::shared_ptr<Portal>> sector1_exits; | ||
|
||
/** | ||
* Direction of the portal | ||
*/ | ||
PortalDirection direction; | ||
|
||
/** | ||
* Start cell x coordinate | ||
*/ | ||
size_t cell_start_x; | ||
|
||
/** | ||
* Start cell y coordinate | ||
*/ | ||
size_t cell_start_y; | ||
|
||
/** | ||
* End cell x coordinate | ||
*/ | ||
size_t cell_end_x; | ||
|
||
/** | ||
* End cell y coordinate | ||
*/ | ||
size_t cell_end_y; | ||
}; | ||
} // namespace openage::path |