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

Merged
merged 32 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
64dd525
Add dirty flag and integrate
dmwever Dec 4, 2024
2110ff2
Update libopenage/pathfinding/cost_field.cpp
dmwever Dec 6, 2024
5dcc8a8
Add const to time_t and improve docstrings
dmwever Dec 6, 2024
04211fa
change sector is_dirty to a reference
dmwever Dec 6, 2024
7f75f53
Change fieldCache to unique_ptr and add docs
dmwever Dec 6, 2024
219431d
Grammar
dmwever Dec 6, 2024
305b412
Grammar
dmwever Dec 6, 2024
94101cb
Use contains()
dmwever Dec 6, 2024
3cfdb11
several changes
dmwever Dec 7, 2024
5c41505
next round of changes
dmwever Dec 21, 2024
ced5092
Update libopenage/pathfinding/cost_field.h
dmwever Dec 25, 2024
300b123
- more fixes
dmwever Dec 25, 2024
3cef612
Update cost_field.h
dmwever Jan 2, 2025
4ed876b
Update libopenage/pathfinding/cost_field.h
dmwever Jan 2, 2025
e0fc329
Update libopenage/pathfinding/cost_field.h
dmwever Jan 2, 2025
ba7aec4
Update libopenage/pathfinding/integrator.h
dmwever Jan 2, 2025
f0d923c
Update libopenage/pathfinding/integrator.h
dmwever Jan 2, 2025
d839bc5
Update Demo
dmwever Jan 3, 2025
5249d77
gamestate: Add request time to pathfinding request.
heinezen Jan 13, 2025
1fec0c9
path: Fix warning for cost field member ordering.
heinezen Jan 13, 2025
87776b6
path: Fix missing initialization of integrator's field cache.
heinezen Jan 13, 2025
c5a3130
Fix sanity check complaints.
heinezen Jan 13, 2025
8dba1e1
path: Make is_dirty check const.
heinezen Jan 13, 2025
9b20825
path: Make demo 1 comments more verbose.
heinezen Jan 13, 2025
b43113a
path: Activate cache usage in demo 1.
heinezen Jan 13, 2025
62889e6
patg: Remove 'is_dirty' method from sector code.
heinezen Jan 13, 2025
ec72342
path: Cleanup field cache code.
heinezen Jan 13, 2025
863ba6c
path: Avoid duplicate lookups for field cache in integrator.
heinezen Jan 13, 2025
eb8f73d
Update copying.md
dmwever Jan 13, 2025
dfa9344
- Sanity Fixes
dmwever Jan 16, 2025
378f69c
Add old email for sanity checks
dmwever Jan 16, 2025
0645469
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 :)

Copy link
Member

Choose a reason for hiding this comment

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

I think both mails are in the commits. The GitHub one is used when you apply suggestions to PRs in the web interface.

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