Commit Graph

53 Commits (88ec8a95231341e7962b85716510d414e9f0c424)

Author SHA1 Message Date
clang-format-bot ddb0522bbf
Apply clang-format to code base 2 years ago
elsid 22ee592dd3
Lock TileCachedRecastMeshManager once per changing a cell
To save time on locking mutex and prevent AsyncNavMeshUpdater to use RecastMesh
for a tile in the middle of objects loading.
2 years ago
elsid c15848932b
Separate reading navigator stats and reporting 2 years ago
elsid e9be8b5efe
Show stats for writing and reading navmesh db queue jobs 2 years ago
elsid e1bed86d7e
Do single navigator update per frame
Primarily for crossing cell border case. Each Navigator::update call has a cost.
Doing it multiple times per frame increased frame duration on cell loading.

Call Navigator::wait only when cell has changed but do not use
Scene::hasCellChanged because it doesn't always indicates it.
2 years ago
elsid b1fb42a28c
Cleanup detournavigator includes 2 years ago
elsid 1a5932a669
Move std::ostream& operator<< to .cpp 3 years ago
elsid 1a12c453d6
Support different agent collision shape type for pathfinding
Actors may have different collision shapes. Currently there are axis-aligned
bounding boxes and rotating bounding boxes. With AABB it's required to use
bounding cylinder for navmesh agent to avoid providing paths where actor can't
pass. But for rotating bounding boxes cylinder with diameter equal to the front
face width should be used to not reduce of available paths. For example rats
have rotating bounding box as collision shape because of the difference between
front and side faces width.

* Add agent bounds to navmesh tile db cache key. This is required to distinguish
  tiles for agents with different bounds.
* Increase navmesh version because navmesh tile db cache key and data has changed.
* Move navmesh version to the code to avoid misconfiguration by users.
* Fix all places where wrong half extents were used for pathfinding.
3 years ago
elsid a75c7c49f0
Disable writes to navmeshdb on database is locked error
Simultaneously writing to sqlite3 database is not possible. Process exclusively
locks the database for this. Another process will fail to perform any request
when database is locked. Alternatively it can wait. Handling this situation
properly requires complexity that is not really needed. Users are not expected
to run multiple openmw processes simultaneously using the same navmeshdb.

Before this change running multiple openmw processes using the same navmeshdb
can lead to a crash when first transaction fails to start because there is
exception thrown and not catched.

Remove use of explicit transactions from DbWorker. Handling all possible
transaction states due to different errors brings unnecessary complexity.
Initially they were introduced to increase time between flushes to disk. This
makes sense for navmeshtool because of massive number of writes but for the
engine this is not an issue.
3 years ago
elsid 5b9dd10cbe
Limit max navmeshdb file size
Use "pragma max_page_count" to define max allowed file size in combination with
"pragma page_size" based on a new setting "max navmeshdb file size".

* Stop navmeshtool on the first db error.
* Disable writes to db in the engine on first "database or disk is full"
  SQLite3 error. There is no special error code for this error.
* Change default "write to navmeshdb" to true.
* Use time intervals for transaction duration instead of number of changes.
3 years ago
elsid 05b54cbfb8
Cull navmesh objects by scene bounds
If object is too big iteration over all tiles covering it can take too much
time. Limit bounds to a square around a player position to cover only tiles
that will be present in navmesh based on max tiles number option.

Each object is associated with a set of tiles its present in. Culling can
reduce this set but it has to be update when bounds change position. Do this
in TileCachedRecastMeshManager::setBounds updating the set and adding/removing
objects to the corresponding CachedRecastMeshManagers.
3 years ago
elsid aaf6c82e33
Do not write shapes to navmeshdb when writing is disabled 3 years ago
elsid 96eb8d7be9
Write generated navmesh to navmeshdb
Perform all request to db in a single thread to avoid blocking navmesh
generator threads due to slow write operations.

Write to db navmesh for all changes except update as it done for memory cache.

Batch multiple db operations into a single transaction to speed up writing by
not executing fsync after each insert/update query. All reads are performed in
the same transaction so they see uncommited data.
3 years ago
elsid c9b8ba7b46
Read navmesh tile data from database
When tile is not found in memory cache try to find it in the database.
3 years ago
elsid 0066c446f8
Remove navmesh tiles outside allowed range first
* Change job change type to remove when tile is outside allowed range.
* Swap try number and change type in job priority. To make sure remove jobs
  always processed before any other.
3 years ago
elsid 431501e23a
Remove redundant job distribution between threads
Instead don't take jobs from queue until job for the same tile is processing.
3 years ago
elsid 09b1a2e3c6
Make unchanging Job fields const 3 years ago
elsid 8bca9eec80
Use single set to store pushed tiles 3 years ago
elsid a97b2ced27
Use single map to store last updates 3 years ago
elsid bfcc430822
Use single map to store processing tiles 3 years ago
elsid 902b0f9f84
Store jobs in the same container until they are processed
Push to queue and reorder only iterators.
3 years ago
elsid 8db640289c
Use single set to store pushed jobs for tiles 3 years ago
elsid a99266a60e
Do not measure total navmesh generation duration
This is not a useful thing anymore.
3 years ago
elsid 59f89d22f8
Apply min distance only for not present tiles
To avoid waiting when navmesh update is triggered by transformed object for
already present tiles.
4 years ago
elsid d0ea9c482a
Reorder async navmesh updater jobs when player tile changes
When player tile changes distance to player that is part of jobs priority is
invalidated. So jobs are no longer in the right order. This can lead to
processing of farests tiles first.

Sort queue each time player tile is changed.
4 years ago
elsid 7a51d0db18
Wait until navmesh is generated within given distance around player
Add a setting to change this distance.

To prevent situations when there is not enough navmesh generated and actors
can't find path correctly.
4 years ago
elsid f169f8e6f0
Wait until navmesh is generated for interior cells
Add special loading progress bar.

It should be fast enough to not keep loading screen for noticably long but
will provide better pathfinding for actors inside interior cells.
4 years ago
Bret Curtis f6bead88a9 purge boost/optional.hpp headers 4 years ago
Bret Curtis 62b0781f7d use std::optional instead of boost::optional 4 years ago
fredzio 460e69e92a Get rid of warning: dynamic exception specifications are deprecated 4 years ago
elsid b150d681a9
Update same navmesh tile with limited frequency 5 years ago
elsid bd1ef4dd6d
Add detournavigator test for multiple worker threads 5 years ago
elsid 7502db1570
Add number of thread jobs to update jobs stats 5 years ago
elsid c683dc8565
Lock navmesh tile by thread while processing
To avoid duplicated work on a same tile by different threads.
If tile is locked by another thread, then post job into this thread queue.
6 years ago
elsid 4624f31788
Report navigator stats 6 years ago
elsid f6a1d3cecf
Store weak pointers to navmesh in jobs queue
To avoid useless processing for removed navmeshes.
6 years ago
elsid ff47df4f2c
Repost navmesh update jobs when failed because of out of memory
DT_OUT_OF_MEMORY error is returned when limit of tiles is reached.
6 years ago
elsid b9b8ed177c
Store priority values as named fields 6 years ago
elsid 41319eb2bf
Use new change type for update object
To perform jobs for updated animated objects and doors with lowest
priority.
6 years ago
elsid ed73d130f9
Cache navmesh tiles
Use LRU modification to hold currently used items. Use RecastMesh binary
data for item key.

Store original pointer of btCollisionShape in user pointer to make available
it as an identifier within all duplicates. Use pointer to heights data array
for btHeightfieldTerrainShape.
6 years ago
elsid ae7285e960
Use ScopeGuarded instead of raw mutex 6 years ago
elsid 7c80bb9411
Support multiple threads for async nav mesh updater 6 years ago
elsid 346e9e3141
Add off mesh connections for doors without teleport 6 years ago
elsid c771986c56
Prioritise NavMesh jobs first to remove and last to add
When player move fast enough, tiles update for specific area square
couldn't catch player move. Tiles to be removed are left in the queue
with lower priority then tiles to be added which are nearest to player.
This can lead to overflow for amount of tiles. So we try to do remove
first. But we detect change type approximately using mixed change type,
because even if we do it precise, change type could change while job
is in queue.
6 years ago
elsid 4aba0fa85f
Limit number of NavMesh tiles to add by distance from player tile 6 years ago
elsid d2fd9abd51
Split RecastMesh into tiles 6 years ago
elsid f268ec5d34
Measure total time for NavMesh build from first pop 6 years ago
elsid dd5f4498f6
Increment NavMesh revision on remove or add tile 6 years ago
elsid 70a369f70e
Add command to enable NavMesh render
togglenavmesh or tnm
6 years ago
elsid 1caa18bb4f
Use one recast mesh for all jobs 6 years ago