Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add dirty flag and integrate #1725

Open
wants to merge 34 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
9ea8b58
Add dirty flag and integrate
dmwever Dec 4, 2024
a12b347
Update libopenage/pathfinding/cost_field.cpp
dmwever Dec 6, 2024
73647d4
Add const to time_t and improve docstrings
dmwever Dec 6, 2024
5a17e4e
change sector is_dirty to a reference
dmwever Dec 6, 2024
22e594f
Change fieldCache to unique_ptr and add docs
dmwever Dec 6, 2024
ce77c9f
Grammar
dmwever Dec 6, 2024
d33d4f7
Grammar
dmwever Dec 6, 2024
3adb802
Use contains()
dmwever Dec 6, 2024
6251a72
Merge branch 'master' into Add-Cost-Field-Dirty-Flag
dmwever Dec 7, 2024
fd72608
several changes
dmwever Dec 7, 2024
b9f6bd1
next round of changes
dmwever Dec 21, 2024
6f2c407
Update libopenage/pathfinding/cost_field.h
dmwever Dec 25, 2024
e7fb51e
- more fixes
dmwever Dec 25, 2024
4561388
Update cost_field.h
dmwever Jan 2, 2025
bf33b18
Update libopenage/pathfinding/cost_field.h
dmwever Jan 2, 2025
6e6c7a6
Update libopenage/pathfinding/cost_field.h
dmwever Jan 2, 2025
cf3cd96
Update libopenage/pathfinding/integrator.h
dmwever Jan 2, 2025
d5cfcf0
Update libopenage/pathfinding/integrator.h
dmwever Jan 2, 2025
904f44b
Update Demo
dmwever Jan 3, 2025
91df9f5
Merge remote-tracking branch 'upstream/master' into Add-Cost-Field-Di…
dmwever Jan 3, 2025
9040a3c
gamestate: Add request time to pathfinding request.
heinezen Jan 13, 2025
1ad186c
path: Fix warning for cost field member ordering.
heinezen Jan 13, 2025
e30126a
path: Fix missing initialization of integrator's field cache.
heinezen Jan 13, 2025
cbb5f3b
Fix sanity check complaints.
heinezen Jan 13, 2025
dea6b18
path: Make is_dirty check const.
heinezen Jan 13, 2025
9b506b9
path: Make demo 1 comments more verbose.
heinezen Jan 13, 2025
b73fe42
path: Activate cache usage in demo 1.
heinezen Jan 13, 2025
c2de560
patg: Remove 'is_dirty' method from sector code.
heinezen Jan 13, 2025
f378c52
path: Cleanup field cache code.
heinezen Jan 13, 2025
b971a7b
path: Avoid duplicate lookups for field cache in integrator.
heinezen Jan 13, 2025
d771627
Update copying.md
dmwever Jan 13, 2025
48a6955
- Sanity Fixes
dmwever Jan 16, 2025
4b4dd25
Add old email for sanity checks
dmwever Jan 16, 2025
66e4004
Update .mailmap
dmwever Jan 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .mailmap
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ Tobias Feldballe <[email protected]> <[email protected]>
Tobias Feldballe <[email protected]> <[email protected]>
Jonas Borchelt <[email protected]>
Derek Frogget <[email protected]> <[email protected]>
Nikhil Ghosh <[email protected]>
Nikhil Ghosh <[email protected]>
David Wever <[email protected]> <[email protected]>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you don't need this entry if you update and fix your mail/author name in all the commits of this pull request. since they are not merged yet, this can easily be done - the file is for commits that have been merged already :)

1 change: 1 addition & 0 deletions copying.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ _the openage authors_ are:
| Jeremiah Morgan | jere8184 | jeremiahmorgan dawt bham à outlook dawt com |
| Tobias Alam | alamt22 | tobiasal à umich dawt edu |
| Alex Zhuohao He | ZzzhHe | zhuohao dawt he à outlook dawt com |
| David Wever | dmwever | dmwever à crimson dawt ua dawt edu |

If you're a first-time committer, add yourself to the above list. This is not
just for legal reasons, but also to keep an overview of all those nicknames.
Expand Down
2 changes: 1 addition & 1 deletion libopenage/gamestate/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Map::Map(const std::shared_ptr<GameState> &state,

auto sector = grid->get_sector(chunk_idx);
auto cost_field = sector->get_cost_field();
cost_field->set_cost(tile_idx, path_cost.second);
cost_field->set_cost(tile_idx, path_cost.second, time::TIME_ZERO);
}
}
}
Expand Down
8 changes: 5 additions & 3 deletions libopenage/gamestate/system/move.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2023-2024 the openage authors. See copying.md for legal info.
// Copyright 2023-2025 the openage authors. See copying.md for legal info.

#include "move.h"

Expand Down Expand Up @@ -37,7 +37,8 @@ namespace openage::gamestate::system {
std::vector<coord::phys3> find_path(const std::shared_ptr<path::Pathfinder> &pathfinder,
path::grid_id_t grid_id,
const coord::phys3 &start,
const coord::phys3 &end) {
const coord::phys3 &end,
const time::time_t &start_time) {
auto start_tile = start.to_tile();
auto end_tile = end.to_tile();

Expand All @@ -46,6 +47,7 @@ std::vector<coord::phys3> find_path(const std::shared_ptr<path::Pathfinder> &pat
grid_id,
start_tile,
end_tile,
start_time,
};
auto tile_path = pathfinder->get_path(request);

Expand Down Expand Up @@ -122,7 +124,7 @@ const time::time_t Move::move_default(const std::shared_ptr<gamestate::GameEntit
auto map = state->get_map();
auto pathfinder = map->get_pathfinder();
auto grid_id = map->get_grid_id(move_path_grid->get_name());
auto waypoints = find_path(pathfinder, grid_id, current_pos, destination);
auto waypoints = find_path(pathfinder, grid_id, current_pos, destination, start_time);

// use waypoints for movement
double total_time = 0;
Expand Down
1 change: 1 addition & 0 deletions libopenage/pathfinding/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
add_sources(libopenage
cost_field.cpp
definitions.cpp
field_cache.cpp
flow_field.cpp
grid.cpp
integration_field.cpp
Expand Down
26 changes: 16 additions & 10 deletions libopenage/pathfinding/cost_field.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2024-2024 the openage authors. See copying.md for legal info.
// Copyright 2024-2025 the openage authors. See copying.md for legal info.

#include "cost_field.h"

Expand All @@ -13,6 +13,7 @@ namespace openage::path {

CostField::CostField(size_t size) :
size{size},
valid_until{time::TIME_MIN},
cells(this->size * this->size, COST_MIN) {
log::log(DBG << "Created cost field with size " << this->size << "x" << this->size);
}
Expand All @@ -33,29 +34,34 @@ cost_t CostField::get_cost(size_t idx) const {
return this->cells.at(idx);
}

void CostField::set_cost(const coord::tile_delta &pos, cost_t cost) {
this->cells[pos.ne + pos.se * this->size] = cost;
void CostField::set_cost(const coord::tile_delta &pos, cost_t cost, const time::time_t &valid_until) {
this->set_cost(pos.ne + pos.se * this->size, cost, valid_until);
}

void CostField::set_cost(size_t x, size_t y, cost_t cost) {
this->cells[x + y * this->size] = cost;
}

void CostField::set_cost(size_t idx, cost_t cost) {
this->cells[idx] = cost;
void CostField::set_cost(size_t x, size_t y, cost_t cost, const time::time_t &valid_until) {
this->set_cost(x + y * this->size, cost, valid_until);
}

const std::vector<cost_t> &CostField::get_costs() const {
return this->cells;
}

void CostField::set_costs(std::vector<cost_t> &&cells) {
void CostField::set_costs(std::vector<cost_t> &&cells, const time::time_t &valid_until) {
ENSURE(cells.size() == this->cells.size(),
"cells vector has wrong size: " << cells.size()
<< "; expected: "
<< this->cells.size());

this->cells = std::move(cells);
this->valid_until = valid_until;
}

bool CostField::is_dirty(const time::time_t &time) const {
return time >= this->valid_until;
}

void CostField::clear_dirty() {
this->valid_until = time::TIME_MAX;
}

} // namespace openage::path
37 changes: 32 additions & 5 deletions libopenage/pathfinding/cost_field.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// Copyright 2024-2024 the openage authors. See copying.md for legal info.
// Copyright 2024-2025 the openage authors. See copying.md for legal info.

#pragma once

#include <cstddef>
#include <vector>

#include "pathfinding/types.h"
#include "time/time.h"


namespace openage {
Expand Down Expand Up @@ -64,25 +65,31 @@ class CostField {
*
* @param pos Coordinates of the cell (relative to field origin).
* @param cost Cost to set.
* @param valid_until Time at which the cost value expires.
*/
void set_cost(const coord::tile_delta &pos, cost_t cost);
void set_cost(const coord::tile_delta &pos, cost_t cost, const time::time_t &valid_until);

/**
* Set the cost at a specified position.
*
* @param x X-coordinate of the cell.
* @param y Y-coordinate of the cell.
* @param cost Cost to set.
* @param valid_until Time at which the cost value expires.
*/
void set_cost(size_t x, size_t y, cost_t cost);
void set_cost(size_t x, size_t y, cost_t cost, const time::time_t &valid_until);

/**
* Set the cost at a specified position.
*
* @param idx Index of the cell.
* @param cost Cost to set.
* @param valid_until Time at which the cost value expires.
*/
void set_cost(size_t idx, cost_t cost);
inline void set_cost(size_t idx, cost_t cost, const time::time_t &valid_until) {
this->cells[idx] = cost;
this->valid_until = valid_until;
}

/**
* Get the cost field values.
Expand All @@ -95,15 +102,35 @@ class CostField {
* Set the cost field values.
*
* @param cells Cost field values.
* @param valid_until Time at which the cost value expires.
*/
void set_costs(std::vector<cost_t> &&cells);
void set_costs(std::vector<cost_t> &&cells, const time::time_t &changed);

/**
* Check if the cost field is dirty at the specified time.
*
* @param time Time of access to the cost field.
*
* @return Whether the cost field is dirty.
*/
bool is_dirty(const time::time_t &time) const;

/**
* Clear the dirty flag.
*/
void clear_dirty();

private:
/**
* Side length of the field.
*/
size_t size;

/**
* Time the cost field expires.
*/
time::time_t valid_until;

/**
* Cost field values.
*/
Expand Down
22 changes: 12 additions & 10 deletions libopenage/pathfinding/demo/demo_0.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2024-2024 the openage authors. See copying.md for legal info.
// Copyright 2024-2025 the openage authors. See copying.md for legal info.

#include "demo_0.h"

Expand Down Expand Up @@ -33,15 +33,17 @@ void path_demo_0(const util::Path &path) {

// Cost field with some obstacles
auto cost_field = std::make_shared<CostField>(field_length);
cost_field->set_cost(coord::tile_delta{0, 0}, COST_IMPASSABLE);
cost_field->set_cost(coord::tile_delta{1, 0}, 254);
cost_field->set_cost(coord::tile_delta{4, 3}, 128);
cost_field->set_cost(coord::tile_delta{5, 3}, 128);
cost_field->set_cost(coord::tile_delta{6, 3}, 128);
cost_field->set_cost(coord::tile_delta{4, 4}, 128);
cost_field->set_cost(coord::tile_delta{5, 4}, 128);
cost_field->set_cost(coord::tile_delta{6, 4}, 128);
cost_field->set_cost(coord::tile_delta{1, 7}, COST_IMPASSABLE);

const time::time_t time = time::TIME_ZERO;
cost_field->set_cost(coord::tile_delta{0, 0}, COST_IMPASSABLE, time);
cost_field->set_cost(coord::tile_delta{1, 0}, 254, time);
cost_field->set_cost(coord::tile_delta{4, 3}, 128, time);
cost_field->set_cost(coord::tile_delta{5, 3}, 128, time);
cost_field->set_cost(coord::tile_delta{6, 3}, 128, time);
cost_field->set_cost(coord::tile_delta{4, 4}, 128, time);
cost_field->set_cost(coord::tile_delta{5, 4}, 128, time);
cost_field->set_cost(coord::tile_delta{6, 4}, 128, time);
cost_field->set_cost(coord::tile_delta{1, 7}, COST_IMPASSABLE, time);
log::log(INFO << "Created cost field");

// Create an integration field from the cost field
Expand Down
39 changes: 32 additions & 7 deletions libopenage/pathfinding/demo/demo_1.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2024-2024 the openage authors. See copying.md for legal info.
// Copyright 2024-2025 the openage authors. See copying.md for legal info.

#include "demo_1.h"

Expand Down Expand Up @@ -30,29 +30,42 @@ void path_demo_1(const util::Path &path) {
// Initialize the cost field for each sector.
for (auto &sector : grid->get_sectors()) {
auto cost_field = sector->get_cost_field();
std::vector<cost_t> sector_cost = sectors_cost.at(sector->get_id());
cost_field->set_costs(std::move(sector_cost));

// Read the data from the preconfigured table
std::vector<cost_t> sector_cost = SECTORS_COST.at(sector->get_id());

// Set the cost field for the sector
cost_field->set_costs(std::move(sector_cost), time::TIME_MAX);
}

// Initialize portals between sectors.
// Initialize portals between sectors
util::Vector2s grid_size = grid->get_size();
portal_id_t portal_id = 0;
for (size_t y = 0; y < grid_size[1]; y++) {
for (size_t x = 0; x < grid_size[0]; x++) {
// For each sector on the grid, we will seatch for portals to the east and south
// sectors and connect them

auto sector = grid->get_sector(x, y);

if (x < grid_size[0] - 1) {
// Check the sector to the east
auto neighbor = grid->get_sector(x + 1, y);
auto portals = sector->find_portals(neighbor, PortalDirection::EAST_WEST, portal_id);

// Add the portals to the sector and the neighbor
for (auto &portal : portals) {
sector->add_portal(portal);
neighbor->add_portal(portal);
}
portal_id += portals.size();
}
if (y < grid_size[1] - 1) {
// Check the sector to the south
auto neighbor = grid->get_sector(x, y + 1);
auto portals = sector->find_portals(neighbor, PortalDirection::NORTH_SOUTH, portal_id);

// Add the portals to the sector and the neighbor
for (auto &portal : portals) {
sector->add_portal(portal);
neighbor->add_portal(portal);
Expand All @@ -62,7 +75,8 @@ void path_demo_1(const util::Path &path) {
}
}

// Connect portals inside sectors.
// Connect portals that can mutually reach each other
// within the same sector
for (auto sector : grid->get_sectors()) {
sector->connect_exits();

Expand All @@ -81,19 +95,25 @@ void path_demo_1(const util::Path &path) {
auto pathfinder = std::make_shared<path::Pathfinder>();
pathfinder->add_grid(grid);

// Add a timer to measure the pathfinding speed
util::Timer timer;

// Create a path request and get the path
// Create a path request from one end of the grid to the other
coord::tile start{2, 26};
coord::tile target{36, 2};

PathRequest path_request{
grid->get_id(),
start,
target,
time::TIME_ZERO,
};

// Initialize the portal nodes of the grid
// This is used for the A* pathfinding search at the beginning
grid->init_portal_nodes();

timer.start();
// Let the pathfinder search for a path
Path path_result = pathfinder->get_path(path_request);
timer.stop();

Expand All @@ -109,8 +129,11 @@ void path_demo_1(const util::Path &path) {
auto render_manager = std::make_shared<RenderManager1>(qtapp, window, path, grid);
log::log(INFO << "Created render manager for pathfinding demo");

// Callbacks for mouse button events
// Used to set the start and target cells for pathfinding
window->add_mouse_button_callback([&](const QMouseEvent &ev) {
if (ev.type() == QEvent::MouseButtonRelease) {
// From the mouse position, calculate the position/cell on the grid
auto cell_count_x = grid->get_size()[0] * grid->get_sector_size();
auto cell_count_y = grid->get_size()[1] * grid->get_sector_size();
auto window_size = window->get_size();
Expand All @@ -127,6 +150,7 @@ void path_demo_1(const util::Path &path) {
grid->get_id(),
start,
target,
time::TIME_ZERO,
};

timer.reset();
Expand All @@ -147,6 +171,7 @@ void path_demo_1(const util::Path &path) {
grid->get_id(),
start,
target,
time::TIME_ZERO,
};

timer.reset();
Expand Down
4 changes: 2 additions & 2 deletions libopenage/pathfinding/demo/demo_1.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2024-2024 the openage authors. See copying.md for legal info.
// Copyright 2024-2025 the openage authors. See copying.md for legal info.

#pragma once

Expand Down Expand Up @@ -182,7 +182,7 @@ class RenderManager1 {

// Cost for the sectors in the grid
// taken from Figure 23.1 in "Crowd Pathfinding and Steering Using Flow Field Tiles"
const std::vector<std::vector<cost_t>> sectors_cost = {
const std::vector<std::vector<cost_t>> SECTORS_COST = {
{
// clang-format off
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
Expand Down
Loading